CAFE

기타

[30기 이건]WebSocket 서버연결

작성자30기 이건|작성시간15.10.26|조회수298 목록 댓글 0


웹소켓 접속과정은 다음과 같습니다.



순서대로 C#으로 코드를 작성해 보겠습니다


private static TcpListener listener;

static void Main(string[] args)

{            

listener = new TcpListener(IPAddress.Loopback, 8080);

     listener.Start();

Listen();

}

Tcp 네트워크 클라이언트에서 연결을 수신합니다.


private static void Listen()

{

while (true)

     {

TcpClient client = listener.AcceptTcpClient();

          NetworkStream ns = client.GetStream();

          Request(ns);

}

}

//보류 중인 연결을 받아들입니다.

//그 후 클라이언트가 보내는 요청 헤더를 분석하는 Request메서드를 정의합니다.

private static void Request(NetworkStream ns)

{

     byte[] httpHeader = new byte[2048];

     ns.Read(httpHeader, 0, httpHeader.Length);

     string header = Encoding.Default.GetString(httpHeader).Trim('\0');

      if (header.ToLower().Contains("get / http/1.1"))

      {

          if (header.ToLower().Contains("upgrade: websocket"))

          {

              string[] elements = header.Split("\r\n".ToCharArray());

              foreach (string element in elements)

              {

                   if (element.ToLower().Contains("sec-websocket-key"))

                   {

                        string sec_key = element.Split(" ".ToCharArray())[1];

                        Response(ns, sec_key);

                        break;

                    }

                }

           }

           else

           {

               Response(ns);

           }

      }

}

//Request 메서드에서는 요청헤더에 웹소켓 프로토콜 스위칭 요청이 없을 경우 미리 준비된 html 파일을 웹브라우저에 띄어주는 응답 헤더 메서드와 웹소켓 응답헤더를 정의합니다.

private static string html_file = "client.html";

private static void Response(NetworkStream ns)

{

    FileInfo fi = new FileInfo(html_file);

    byte[] data = new byte[fi.Length];

    FileStream fs = new FileStream(html_file, FileMode.Open);

    fs.Read(data, 0, data.Length);

    fs.Close();

 

   string header = "HTTP/1.1 200 OK\r\n";

   header += "Content-Length: " + data.Length.ToString() + "\r\n";

   header += "\r\n";

   ns.Write(Encoding.Default.GetBytes(header), 0, Encoding.Default.GetBytes(header).Length);

   ns.Write(data, 0, data.Length);

}

//html 파일을 웹브라우저에게 띄어주는 응답헤더를 보내주는 메서드


private static string key_value = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

private static void Response(NetworkStream ns, string sec_key)

{

    Console.WriteLine("Response..\n");

    SHA1 sha = new SHA1CryptoServiceProvider();

    byte[] key = Encoding.Default.GetBytes(sec_key + key_value);

    byte[] hash = sha.ComputeHash(key);

 

    string accept_key = Convert.ToBase64String(hash);

    string header = "HTTP/1.1 101 Switching Protocols\r\n"

          + "Upgrade: WebSocket\r\n" + "Connection: Upgrade\r\n"

          + "Sec-WebSocket-Accept: " + accept_key + "\r\n"

          + "\r\n";

    byte[] byte_header = Encoding.Default.GetBytes(header);

    ns.Write(byte_header, 0, byte_header.Length);

}

// 웹소켓 프로토콜 스위칭 응답 헤더

//스위칭 프로토콜을 하기 위해서는 핸드쉐이크 과정이 필요한데 웹소켓 핸드쉐이크 과정은

//요청헤더에 포함된 sec-websocket-key에 있는 키값 뒤에 미리 정의된 문자열인 "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"를 더한후 SHA-1 알고리즘을 통해 암호화를 한 값을 Base64로 인코딩 한 후 그 값을 응답헤더의 ""Sec-WebSocket-Accept" 에 에 넣어주면 웹소켓의 연결이 완료됩니다.



추가.

//bin/debug/client.html


<!DOCTYPE html>

<html>

<meta charset="utf-8"/>

<head>

    <script type="text/javascript">

        function connect() {

            var ws = new WebSocket("ws://127.0.0.1:8080/"); //웹소켓 연결 


            ws.onopen = function () {   //웹 소켓이 열려 있을 경우 해당 함수 실행

                alert(‎"About to send data");        

            };

            ws.onclose = function () {  //웹 소켓이 닫혀 있을 경우 해당 함수 실행

                alert(‎"닫힌듯");

            };

        };

    </script>

</head>

<body>

    <input type="button" value="클릭" [안내]태그제한으로등록되지않습니다-xxonclick="connect()"/> //버튼에 클릭 이벤트

</body>

</html>



다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼