VioletaBabel

36. 간단한 서버 연결 본문

BCA/5. Websocket-Sharp
36. 간단한 서버 연결
Beabletoet 2018. 6. 4. 13:56

비주얼 스튜디오에서 wpf 앱을 하나 만든 후, 솔루션 탐색기에서 참조에 우클릭 후 nuget 패키지 관리를 누른다.

거기서 websocket을 검색. 제일 위의 websocket-sharp.clone 설치.

(혹시 설치안되면 솔루션 탐색기에서 프로젝트를 우클릭 후, 속성에서 대상 프레임워크를 4.5 이상으로 설정.)


다음으로 프로젝트 우클릭 후 추가 - 클래스.

이름은 Chat로 한다. 그리고 public을 붙여 외부 접근이 가능한 클래스라고 지정해주자. 

거기다가 using WebSocketSharp.Server;를 적어두고 Chat은 WebSocketBehavior를 상속받는다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//Chat.cs
using System;
using System.Threading.Tasks;
using WebSocketSharp;
using WebSocketSharp.Server;
 
namespace _180604_websocketTest
{
    public class Chat : WebSocketBehavior
    {
        private string _suffix;
        public Chat() : this(null
            // 생성자를 그냥 만들 시 밑의 오버로드된 생성자의 인수 suffix에 null을 넣어 실행한다.
        {
 
        }
        public Chat(string suffix)
        {
            _suffix = suffix ?? String.Empty;
            //?? 연산자는 연산자 앞의 값이 null이면 뒤의 값을 대입.
        }
        protected override Task OnMessage(MessageEventArgs e)
        {
            return Sessions.Broadcast(e.Data + _suffix);
        }
    }
}
 
cs



Chat 코드를 작성 후

Echo라는 클래스를 또 만들어준다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//Echo.cs
using System;
using System.Threading.Tasks;
using System.Windows;
using WebSocketSharp;
using WebSocketSharp.Server;
 
namespace _180604_websocketTest
{
    public class Echo : WebSocketBehavior
    {
        protected override async Task OnMessage(MessageEventArgs e)
        {
            switch(e.Opcode)
            {
                case Opcode.Text:
                    var text = await e.Text.ReadToEndAsync().ConfigureAwait(false);
                    text += "\n";
                    MainWindow win = MainWindow.getWindow;
                    win.addText(text);
 
                    await Send(text).ConfigureAwait(false);
                    return;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }
}
 
cs




각 컴퓨터의 80번 포트는 web server

21번 포트는 file transfer protocol

다른 포트 넘버들은 다음과 같다.

 https://ko.wikipedia.org/wiki/TCP/UDP%EC%9D%98_%ED%8F%AC%ED%8A%B8_%EB%AA%A9%EB%A1%9D

https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!--MainWIndow.xaml-->
    <Window x:Class="_180604_websocketTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_180604_websocketTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Name ="Start" Content="Start" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="713,325,0,0" Click="Start_Click"/>
        <Button Name ="Stop" Content="Stop" HorizontalAlignment="Left" Margin="713,362,0,0" VerticalAlignment="Top" Width="75" Click="Stop_Click"/>
        <TextBox Name ="Console" AcceptsReturn="True" HorizontalAlignment="Left" Height="343" TextWrapping="Wrap" Text="" IsReadOnly ="True" VerticalAlignment="Top" Width="653" Margin="34,39,0,0"/>
        <!-- TextBox의 AcceptsReturn이 트루이면 엔터키를 먹는 텍스트박스가 됨. IsReadOnly가 트루면 읽기 전용-->
    </Grid>
</Window>
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//MainWindow.xaml.cs
using System;
using System.Windows;
using WebSocketSharp.Server;
 
namespace _180604_websocketTest
{
    public partial class MainWindow : Window
    {
        private static MainWindow g_Main = null;
        public static MainWindow getWindow
        {
            get
            {
                return g_Main;
            }
        }
        public void addText(string text)
        {
            this.Dispatcher.Invoke
            (
                (Action)(() =>
                {
                    string myText = Console.Text;
                    myText += text;
                    Console.Text = myText;
                })
            );
        }
        public MainWindow()
        {
            InitializeComponent();
            g_Main = this;
        }
 
        private WebSocketServer webSocketServer = null;
 
        private void Start_Click(object sender, RoutedEventArgs e)
        {
            if (webSocketServer != null)
                return;
            Int32 port = 4649;
            webSocketServer = new WebSocketServer(null, port);
 
            webSocketServer.AddWebSocketService<Echo>("/Echo");
            webSocketServer.AddWebSocketService<Chat>("/Chat");
            webSocketServer.AddWebSocketService<Chat>("/ChatWithA", () => new Chat("A"));
            //람다 식의 왼쪽은 입력 매개변수, 오른쪽은 식이나 문 블록.
            //webSocketServer.AddWebSocketService<Chat>("/ChatWithA", chatttttt); // 윗 줄의 람다 식 안쓰려면 이렇게 1(뒤에도 볼 것)
            webSocketServer.Start();
            Console.Text += "서버시작\n";
        }
        /*public Chat chatttttt()
        {
            return new Chat("A");
        }*/ // 람다 식 안쓰려면 이렇게 2
        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            if (webSocketServer != null)
                webSocketServer.Stop();
            webSocketServer = null;
            Console.Text += "서버종료\n";
        }
 
    }
 
}
 
cs



다음과 같이 만들어주면 우선 간단한 서버는 구축이 되었다.


클라이언트 용으로 wpf 앱을 또 만든다.

그 다음 이렇게 코드를 짠다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//Cl.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WebSocketSharp;
 
namespace _180604_websocketClientTest
{
    class Cl
    {
        public Cl()
        {
            StartConnect();
            
        }
        public async Task StartConnect()
        {
            using (WebSocket ws = new WebSocket("ws://localhost:4649/Echo"))
            {
                bool v = await ws.Connect();
                await ws.Send("abcd");
                await ws.Close();
            }
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!--MainWindow.xaml-->
    <Window x:Class="_180604_websocketClientTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_180604_websocketClientTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        
    </Grid>
</Window>
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
 
namespace _180604_websocketClientTest
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Cl c = new Cl();
        }
    }
}
 
cs


'BCA > 5. Websocket-Sharp' 카테고리의 다른 글

37. 채팅 서버 만들기  (0) 2018.06.05
Comments