"Hello World"WebSocket 예제 만들기


85

다음 코드를 작동시킬 수없는 이유를 이해할 수 없습니다. JavaScript로 서버 콘솔 응용 프로그램에 연결하고 싶습니다. 그런 다음 데이터를 서버로 보냅니다.

다음은 서버 코드입니다.

    static void Main(string[] args)
    {            
        TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 9998);
        server.Start();
        var client = server.AcceptTcpClient();
        var stream = client.GetStream();

        while (true)
        {
            var buffer = new byte[1024]; 
            // wait for data to be received
            var bytesRead = stream.Read(buffer, 0, buffer.Length);                
            var r = System.Text.Encoding.UTF8.GetString(buffer);
            // write received data to the console
            Console.WriteLine(r.Substring(0, bytesRead));
        }
    }

다음은 JavaScript입니다.

        var ws = new WebSocket("ws://localhost:9998/service");
        ws.onopen = function () {
            ws.send("Hello World"); // I WANT TO SEND THIS MESSAGE TO THE SERVER!!!!!!!!
        };

        ws.onmessage = function (evt) {
            var received_msg = evt.data;
            alert("Message is received...");
        };
        ws.onclose = function () {
            // websocket is closed.
            alert("Connection is closed...");
        };

이 코드를 실행하면 다음과 같은 일이 발생합니다.

JavaScript를 실행하면 서버가 연결을 수락하고 성공적으로 설정합니다. 하지만 JavaScript는 데이터를 보낼 수 없습니다. send 메소드를 배치 할 때마다 연결이 설정 되어도 전송되지 않습니다. 이 작업을 어떻게 할 수 있습니까?


9
이 "질문"은 더 이상 질문이 아닌 것으로 보이므로 실제로 StackOverflow의 형식에 적합하지 않습니다. FWIW 클라이언트의 메시지되지 암호화 그것의 마스크 프레임의 일부로서 전송 된 임의의 값에 대하여 XOR'ing 그래피 (모호한). 이 프로토콜 세부 정보는 트래픽을 오해 할 수있는 프록시 서버에 대한 중독 공격을 방지하기 위해 존재합니다.
EricLaw

1
감사합니다.이 답변은 매우 유용합니다. :) 이봐, 한 가지만, "static private string guid ="258EAFA5-E914-47DA-95CA-C5AB0DC85B11 ";" 물건은 항상 일정합니까? 그렇지 않은 경우 이러한 값을 어디서 얻을 수 있습니까?
Charmie 2013 년

1
나는이있어 : "A 서버가 클라이언트로 전송하는 모든 프레임을 마스크 안된다"
Charmie

5
원래 질문을 그대로 두어야 할 것입니다. 질문의 목적은 해결책이 아니라 문제를 제시하는 것입니다. 짐작할 수 있듯이 답은 솔루션에 대한 것입니다.
Kehlan Krumme

1
WebSocket URL이 '/ service'(ws : // localhost : 8080 / service)로 끝나는 이유는 무엇입니까? 'ws : // localhost : 8080'이 아닌 이유는 무엇입니까?
andree 2014-06-04

답변:


72

WebSockets는 TCP 스트리밍 연결에 의존하는 프로토콜입니다. WebSockets는 메시지 기반 프로토콜이지만.

자체 프로토콜을 구현하려면 최신의 안정적인 사양 (18/04/12 용) RFC 6455 를 사용하는 것이 좋습니다 . 이 사양에는 핸드 셰이크 및 프레이밍과 관련된 모든 필요한 정보가 포함되어 있습니다. 브라우저 측과 서버 측에서 동작하는 시나리오에 대한 대부분의 설명. 코드를 구현하는 동안 서버 측에 관한 권장 사항을 따르는 것이 좋습니다.

간단히 말해서 다음과 같이 WebSocket으로 작업하는 것을 설명하겠습니다.

  1. 서버 소켓 (System.Net.Sockets)을 생성 하여 특정 포트에 바인딩하고 비동기식 연결 수락으로 계속 수신합니다. 그런 것 :

    소켓 serverSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
    serverSocket.Bind (new IPEndPoint (IPAddress.Any, 8080));
    serverSocket.Listen (128);
    serverSocket.BeginAccept (null, 0, OnAccept, null);
  2. 핸드 셰이크를 구현할 "OnAccept"함수를 수락 해야합니다 . 미래에는 시스템이 초당 엄청난 양의 연결을 처리하도록되어 있다면 다른 스레드에 있어야합니다.

    private void OnAccept (IAsyncResult result) {
    {
        소켓 클라이언트 = null;
        if (serverSocket! = null && serverSocket.IsBound) {
            클라이언트 = serverSocket.EndAccept (result);
        }
        if (client! = null) {
            / * ClientSocket 핸드 셰이 킹 및 관리 * /
        }
    } catch (SocketException 예외) {
    
    } 드디어 {
        if (serverSocket! = null && serverSocket.IsBound) {
            serverSocket.BeginAccept (null, 0, OnAccept, null);
        }
    }
    }
  3. 연결이 완료되면 핸드 셰이크 를해야 합니다. 1.3 Opening Handshake 사양에 따라 연결이 설정되면 몇 가지 정보가 포함 된 기본 HTTP 요청을 받게됩니다. 예:

    GET / chat HTTP / 1.1
    호스트 : server.example.com
    업그레이드 : websocket
    연결 : 업그레이드
    Sec-WebSocket-Key : dGhlIHNhbXBsZSBub25jZQ ==
    출처 : http://example.com
    Sec-WebSocket-Protocol : 채팅, 슈퍼 채팅
    Sec-WebSocket- 버전 : 13

    이 예제는 프로토콜 13 버전을 기반으로합니다. 이전 버전에는 약간의 차이가 있지만 대부분 최신 버전은 상호 호환됩니다. 다른 브라우저에서 추가 데이터를 보낼 수 있습니다. 예를 들어 브라우저 및 OS 세부 정보, 캐시 및 기타.

    제공된 핸드 셰이크 세부 정보를 기반으로 응답 줄을 생성해야합니다. 대부분 동일하지만 제공된 Sec-WebSocket-Key를 기반으로하는 Accpet-Key를 포함합니다. 사양 1.3에서는 응답 키를 생성하는 방법을 명확하게 설명합니다. 다음은 V13에서 사용한 기능입니다.

    static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    private string AcceptKey (ref string key) {
        string longKey = key + guid;
        SHA1 sha1 = SHA1CryptoServiceProvider.Create ();
        byte [] hashBytes = sha1.ComputeHash (System.Text.Encoding.ASCII.GetBytes (longKey));
        return Convert.ToBase64String (hashBytes);
    }
    

    핸드 셰이크 답변은 다음과 같습니다.

    HTTP / 1.1 101 스위칭 프로토콜
    업그레이드 : websocket
    연결 : 업그레이드
    Sec-WebSocket-Accept : s3pPLMBiTxaQ9kYGzzhZRbK + xOo =

    하지만 수락 키는 클라이언트에서 제공 한 키와 이전에 제공 한 AcceptKey 메서드를 기반으로 생성 된 키 여야합니다. 또한 수락 키의 마지막 문자 뒤에 두 개의 새 줄 "\ r \ n \ r \ n"을 입력했는지 확인하십시오.

  4. 서버에서 핸드 셰이크 응답을 보낸 후 클라이언트는 " onopen "기능을 트리거해야 합니다. 즉, 나중에 메시지를 보낼 수 있습니다.
  5. 메시지는 원시 형식으로 전송되지 않지만 데이터 프레이밍이 있습니다. 그리고 클라이언트에서 서버로도 메시지 헤더에 제공된 4 바이트를 기반으로 데이터에 대한 마스킹을 구현합니다. 서버에서 클라이언트로 데이터에 마스킹을 적용 할 필요는 없습니다. 섹션 5. 데이터 프레이밍 사양을 읽으십시오 . 여기 내 구현에서 복사하여 붙여 넣습니다. 바로 사용할 수있는 코드가 아니며 수정해야합니다. WebSocket 프레이밍으로 읽기 / 쓰기에 대한 아이디어와 전체 논리를 제공하기 위해 게시하고 있습니다. 이 링크로 이동합니다 .
  6. 프레이밍이 구현 된 후 소켓을 사용하여 올바른 방식으로 데이터를 수신하는지 확인하십시오. 예를 들어 TCP는 여전히 스트림 기반 프로토콜이기 때문에 일부 메시지가 하나로 병합되는 것을 방지합니다. 즉, 특정 양의 바이트 만 읽어야합니다. 메시지 길이는 항상 헤더를 기반으로하며 자체 헤더에 데이터 길이 세부 정보를 제공합니다. 따라서 Socket에서 데이터를 수신 할 때 먼저 2 바이트를 수신하고 프레이밍 사양에 따라 헤더에서 세부 정보를 가져온 다음 마스크가 추가 4 바이트를 제공 한 다음 데이터 길이에 따라 1, 4 또는 8 바이트가 될 수있는 길이를 가져옵니다. 그리고 데이터 자체. 읽은 후 디 마스킹을 적용하면 메시지 데이터를 사용할 수 있습니다.
  7. 일부 데이터 프로토콜 을 사용하고 싶을 수 있습니다. 트래픽 경제로 인해 JSON을 사용하고 JavaScript의 클라이언트 측에서 사용하기 쉽습니다. 서버 측의 경우 일부 구문 분석기를 확인할 수 있습니다. 많은 것들이 있습니다. 구글이 정말 도움이 될 수 있습니다.

자체 WebSockets 프로토콜을 구현하면 확실히 프로토콜 자체를 제어 할 수있을뿐만 아니라 얻을 수있는 몇 가지 이점과 훌륭한 경험이 있습니다. 그러나이를 수행하는 데 약간의 시간을 할애하고 구현의 신뢰성이 높은지 확인해야합니다.

동시에 Google이 (다시) 충분한 솔루션을 사용할 준비가되어 있는지 살펴볼 수 있습니다.


나는 악수에 갇혀있는 것 같다. 새 연결이 수신되면 긴 키와 짧은 키의 sha1 해시를 클라이언트에 보내야합니다. 맞습니까?
Tono Nam

섹션 3에서 더 많은 정보를 추가했습니다. 서버 측의 핸드 셰이크에 대한 자세한 내용을 설명합니다.
moka

1
또한 요청 프로토콜이 제공되는 경우 Sec-WebSocket-Protocol 라인에 대한 응답으로 동일하게 사용하십시오. 그러나 요청에 제공된 경우에만. 또한 응답을 위해 버전이 필요하지 않습니다. 그리고 끝에 다른 NewLine을 추가합니다. 또한 UTF8을 사용하여 인코딩 된 전체 응답 문자열을 전송합니다. Encoding.UTF8.GetBytes (responseBytes)
moka

우리는 가깝습니다. 도움을 주셔서 감사합니다. 지금 메시지를 보낼 수 있지만 메시지가 암호화되어 있다고 생각합니다. 나는 ... 곧 작업이 시작됩니다 나의 편집에서보세요
토노 남

데이터 프레이밍을 구현해야합니다. 이것은 WebSockets 프로토콜 구현에서 가장 복잡한 부분이라고 생각합니다. 내 구현에서 포스트에 복사-붙여 넣기 코드를 추가 할 것이지만 변경해야 할 사항이 있기 때문에 편집해야하지만 전반적으로 프레임 작업에 대한 아이디어와 논리를 제공합니다.
moka

9

(OP를 대신하여 게시 된 답변) .

이제 데이터를 보낼 수 있습니다. 이것은 귀하의 답변과 @Maksims Mihejevs의 코드 덕분에 프로그램의 새 버전입니다.

섬기는 사람

using System;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static Socket serverSocket = new Socket(AddressFamily.InterNetwork, 
        SocketType.Stream, ProtocolType.IP);
        static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

        static void Main(string[] args)
        {            
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080));
            serverSocket.Listen(128);
            serverSocket.BeginAccept(null, 0, OnAccept, null);            
            Console.Read();
        }

        private static void OnAccept(IAsyncResult result)
        {
            byte[] buffer = new byte[1024];
            try
            {
                Socket client = null;
                string headerResponse = "";
                if (serverSocket != null && serverSocket.IsBound)
                {
                    client = serverSocket.EndAccept(result);
                    var i = client.Receive(buffer);
                    headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0,i);
                    // write received data to the console
                    Console.WriteLine(headerResponse);

                }
                if (client != null)
                {
                    /* Handshaking and managing ClientSocket */

                    var key = headerResponse.Replace("ey:", "`")
                              .Split('`')[1]                     // dGhlIHNhbXBsZSBub25jZQ== \r\n .......
                              .Replace("\r", "").Split('\n')[0]  // dGhlIHNhbXBsZSBub25jZQ==
                              .Trim();

                    // key should now equal dGhlIHNhbXBsZSBub25jZQ==
                    var test1 = AcceptKey(ref key);

                    var newLine = "\r\n";

                    var response = "HTTP/1.1 101 Switching Protocols" + newLine
                         + "Upgrade: websocket" + newLine
                         + "Connection: Upgrade" + newLine
                         + "Sec-WebSocket-Accept: " + test1 + newLine + newLine
                         //+ "Sec-WebSocket-Protocol: chat, superchat" + newLine
                         //+ "Sec-WebSocket-Version: 13" + newLine
                         ;

                    // which one should I use? none of them fires the onopen method
                    client.Send(System.Text.Encoding.UTF8.GetBytes(response));

                    var i = client.Receive(buffer); // wait for client to send a message

                    // once the message is received decode it in different formats
                    Console.WriteLine(Convert.ToBase64String(buffer).Substring(0, i));                    

                    Console.WriteLine("\n\nPress enter to send data to client");
                    Console.Read();

                    var subA = SubArray<byte>(buffer, 0, i);
                    client.Send(subA);
                    Thread.Sleep(10000);//wait for message to be send


                }
            }
            catch (SocketException exception)
            {
                throw exception;
            }
            finally
            {
                if (serverSocket != null && serverSocket.IsBound)
                {
                    serverSocket.BeginAccept(null, 0, OnAccept, null);
                }
            }
        }

        public static T[] SubArray<T>(T[] data, int index, int length)
        {
            T[] result = new T[length];
            Array.Copy(data, index, result, 0, length);
            return result;
        }

        private static string AcceptKey(ref string key)
        {
            string longKey = key + guid;
            byte[] hashBytes = ComputeHash(longKey);
            return Convert.ToBase64String(hashBytes);
        }

        static SHA1 sha1 = SHA1CryptoServiceProvider.Create();
        private static byte[] ComputeHash(string str)
        {
            return sha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(str));
        }
    }
}

자바 스크립트 :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script type="text/javascript">
        function connect() {
            var ws = new WebSocket("ws://localhost:8080/service");
            ws.onopen = function () {
                alert("About to send data");
                ws.send("Hello World"); // I WANT TO SEND THIS MESSAGE TO THE SERVER!!!!!!!!
                alert("Message sent!");
            };

            ws.onmessage = function (evt) {
                alert("About to receive data");
                var received_msg = evt.data;
                alert("Message received = "+received_msg);
            };
            ws.onclose = function () {
                // websocket is closed.
                alert("Connection is closed...");
            };
        };


    </script>
</head>
<body style="font-size:xx-large" >
    <div>
    <a href="#" onclick="connect()">Click here to start</a></div>
</body>
</html>

이 코드를 실행하면 클라이언트와 서버 모두에서 데이터를 보내고받을 수 있습니다. 유일한 문제는 메시지가 서버에 도착할 때 암호화된다는 것입니다. 프로그램 실행 방법은 다음과 같습니다.

여기에 이미지 설명 입력

클라이언트의 메시지가 어떻게 암호화되는지 확인하십시오.


2
예에 문제가 있습니다. Enter 키를 누르면 연결이 닫힙니다.
Richard Aguirre

@RichardAguirre : OP를 대신하여이 글을 게시했습니다 (답변의 첫 번째 줄 참조)-현재 그들은 귀하의 메시지에 대한 알림을받지 않을 것입니다. 질문 아래에서 핑을 시도 할 수 있지만 그보다 훨씬 더 자세한 정보가 필요할 수 있습니다.
halfer

6

WebSocket은 클라이언트와 서버 간의 핸드 셰이크 를 포함 하는 프로토콜구현됩니다 . 나는 그들이 일반 소켓처럼 작동한다고 생각하지 않습니다. 프로토콜을 읽고 응용 프로그램이이를 이야기하도록하십시오. 또는 기존 WebSocket 라이브러리 또는 WebSocket API 가있는 .Net4.5beta를 사용 합니다.


물론 그들은 일반 소켓과 매우 유사하게 작동합니다. 소켓은 응용 프로그램 프로토콜보다 낮은 수준이므로 종속되지 않습니다. 즉, 소켓에서 FTP, SMTP, HTTP, WebSockets 등을 실행할 수 있습니다. 프로토콜을 올바르게 따르거나 아무도 서버와 통신 할 수 없는지 확인하는 것은 구현 자에게 달려 있습니다.
SRM

4

(1 월 19 일 현재) 간단한 작업 예제를 찾을 수 없었으므로 여기에 업데이트 된 버전이 있습니다. 크롬 버전 71.0.3578.98이 있습니다.

C # Websocket 서버 :

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;

namespace WebSocketServer
{
    class Program
    {
    static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
    static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

    static void Main(string[] args)
    {
        serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080));
        serverSocket.Listen(1); //just one socket
        serverSocket.BeginAccept(null, 0, OnAccept, null);
        Console.Read();
    }

    private static void OnAccept(IAsyncResult result)
    {
        byte[] buffer = new byte[1024];
        try
        {
            Socket client = null;
            string headerResponse = "";
            if (serverSocket != null && serverSocket.IsBound)
            {
                client = serverSocket.EndAccept(result);
                var i = client.Receive(buffer);
                headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0, i);
                // write received data to the console
                Console.WriteLine(headerResponse);
                Console.WriteLine("=====================");
            }
            if (client != null)
            {
                /* Handshaking and managing ClientSocket */
                var key = headerResponse.Replace("ey:", "`")
                          .Split('`')[1]                     // dGhlIHNhbXBsZSBub25jZQ== \r\n .......
                          .Replace("\r", "").Split('\n')[0]  // dGhlIHNhbXBsZSBub25jZQ==
                          .Trim();

                // key should now equal dGhlIHNhbXBsZSBub25jZQ==
                var test1 = AcceptKey(ref key);

                var newLine = "\r\n";

                var response = "HTTP/1.1 101 Switching Protocols" + newLine
                     + "Upgrade: websocket" + newLine
                     + "Connection: Upgrade" + newLine
                     + "Sec-WebSocket-Accept: " + test1 + newLine + newLine
                     //+ "Sec-WebSocket-Protocol: chat, superchat" + newLine
                     //+ "Sec-WebSocket-Version: 13" + newLine
                     ;

                client.Send(System.Text.Encoding.UTF8.GetBytes(response));
                var i = client.Receive(buffer); // wait for client to send a message
                string browserSent = GetDecodedData(buffer, i);
                Console.WriteLine("BrowserSent: " + browserSent);

                Console.WriteLine("=====================");
                //now send message to client
                client.Send(GetFrameFromString("This is message from server to client."));
                System.Threading.Thread.Sleep(10000);//wait for message to be sent
            }
        }
        catch (SocketException exception)
        {
            throw exception;
        }
        finally
        {
            if (serverSocket != null && serverSocket.IsBound)
            {
                serverSocket.BeginAccept(null, 0, OnAccept, null);
            }
        }
    }

    public static T[] SubArray<T>(T[] data, int index, int length)
    {
        T[] result = new T[length];
        Array.Copy(data, index, result, 0, length);
        return result;
    }

    private static string AcceptKey(ref string key)
    {
        string longKey = key + guid;
        byte[] hashBytes = ComputeHash(longKey);
        return Convert.ToBase64String(hashBytes);
    }

    static SHA1 sha1 = SHA1CryptoServiceProvider.Create();
    private static byte[] ComputeHash(string str)
    {
        return sha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(str));
    }

    //Needed to decode frame
    public static string GetDecodedData(byte[] buffer, int length)
    {
        byte b = buffer[1];
        int dataLength = 0;
        int totalLength = 0;
        int keyIndex = 0;

        if (b - 128 <= 125)
        {
            dataLength = b - 128;
            keyIndex = 2;
            totalLength = dataLength + 6;
        }

        if (b - 128 == 126)
        {
            dataLength = BitConverter.ToInt16(new byte[] { buffer[3], buffer[2] }, 0);
            keyIndex = 4;
            totalLength = dataLength + 8;
        }

        if (b - 128 == 127)
        {
            dataLength = (int)BitConverter.ToInt64(new byte[] { buffer[9], buffer[8], buffer[7], buffer[6], buffer[5], buffer[4], buffer[3], buffer[2] }, 0);
            keyIndex = 10;
            totalLength = dataLength + 14;
        }

        if (totalLength > length)
            throw new Exception("The buffer length is small than the data length");

        byte[] key = new byte[] { buffer[keyIndex], buffer[keyIndex + 1], buffer[keyIndex + 2], buffer[keyIndex + 3] };

        int dataIndex = keyIndex + 4;
        int count = 0;
        for (int i = dataIndex; i < totalLength; i++)
        {
            buffer[i] = (byte)(buffer[i] ^ key[count % 4]);
            count++;
        }

        return Encoding.ASCII.GetString(buffer, dataIndex, dataLength);
    }

    //function to create  frames to send to client 
    /// <summary>
    /// Enum for opcode types
    /// </summary>
    public enum EOpcodeType
    {
        /* Denotes a continuation code */
        Fragment = 0,

        /* Denotes a text code */
        Text = 1,

        /* Denotes a binary code */
        Binary = 2,

        /* Denotes a closed connection */
        ClosedConnection = 8,

        /* Denotes a ping*/
        Ping = 9,

        /* Denotes a pong */
        Pong = 10
    }

    /// <summary>Gets an encoded websocket frame to send to a client from a string</summary>
    /// <param name="Message">The message to encode into the frame</param>
    /// <param name="Opcode">The opcode of the frame</param>
    /// <returns>Byte array in form of a websocket frame</returns>
    public static byte[] GetFrameFromString(string Message, EOpcodeType Opcode = EOpcodeType.Text)
    {
        byte[] response;
        byte[] bytesRaw = Encoding.Default.GetBytes(Message);
        byte[] frame = new byte[10];

        int indexStartRawData = -1;
        int length = bytesRaw.Length;

        frame[0] = (byte)(128 + (int)Opcode);
        if (length <= 125)
        {
            frame[1] = (byte)length;
            indexStartRawData = 2;
        }
        else if (length >= 126 && length <= 65535)
        {
            frame[1] = (byte)126;
            frame[2] = (byte)((length >> 8) & 255);
            frame[3] = (byte)(length & 255);
            indexStartRawData = 4;
        }
        else
        {
            frame[1] = (byte)127;
            frame[2] = (byte)((length >> 56) & 255);
            frame[3] = (byte)((length >> 48) & 255);
            frame[4] = (byte)((length >> 40) & 255);
            frame[5] = (byte)((length >> 32) & 255);
            frame[6] = (byte)((length >> 24) & 255);
            frame[7] = (byte)((length >> 16) & 255);
            frame[8] = (byte)((length >> 8) & 255);
            frame[9] = (byte)(length & 255);

            indexStartRawData = 10;
        }

        response = new byte[indexStartRawData + length];

        int i, reponseIdx = 0;

        //Add the frame bytes to the reponse
        for (i = 0; i < indexStartRawData; i++)
        {
            response[reponseIdx] = frame[i];
            reponseIdx++;
        }

        //Add the data bytes to the response
        for (i = 0; i < length; i++)
        {
            response[reponseIdx] = bytesRaw[i];
            reponseIdx++;
        }

        return response;
    }
}
}

클라이언트 HTML 및 자바 스크립트 :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script type="text/javascript">
        var socket = new WebSocket('ws://localhost:8080/websession');
        socket.onopen = function() {
           // alert('handshake successfully established. May send data now...');
		   socket.send("Hi there from browser.");
        };
		socket.onmessage = function (evt) {
                //alert("About to receive data");
                var received_msg = evt.data;
                alert("Message received = "+received_msg);
            };
        socket.onclose = function() {
            alert('connection closed');
        };
    </script>
</head>
<body>
</body>
</html>


3

발행물

WebSocket을 사용하고 있으므로 지출이 정확합니다. WebSocket에서 초기 데이터를받은 후 추가 정보가 흐르기 전에 C # 서버에서 핸드 셰이크 메시지를 보내야합니다.

HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: websocket
Connection: Upgrade
WebSocket-Origin: example
WebSocket-Location: something.here
WebSocket-Protocol: 13

그 라인을 따라 뭔가.

w3 또는 google에서 WebSocket이 작동하는 방식에 대해 더 많은 연구를 수행 할 수 있습니다.

링크 및 리소스

다음은 프로토콜 사양입니다. http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76#section-1.3

작업 예 목록 :


또한 UTF8 인코딩을 사용하고 있습니다. ASCII와 같은 다른 것을 사용해야합니까?
Tono Nam

@TonoNam : 내가 아는 한 UTF8 인코딩은 정확합니다. 비록 HTML5 전문가는 아니지만 확실히 알 수 없습니다.
caesay

나는 그것을 사파리와 함께 작동시켰다 !!! 그래도 Google 크롬에서 작동하도록하려면 필요합니다. 모든 예제가 연결되지만 이들 중 어느 것도 성공적으로 데이터를 전송하지 않습니다. 계속 노력하겠습니다. 도움을 주셔서 감사합니다!
Tono Nam

물론 .... 그래도 제대로 작동하지 않으면이 질문을 현상금으로 만들겠습니다! 나는 이것이 작동하는 것을보고 정말로 궁금합니다. 도움을 주셔서 감사합니다
토노 남

프로토콜 사양 링크가 오래되었습니다. Safari는 여전히 이것을 사용하지만 다른 브라우저는 호환되지 않는 RFC 6455 로 이동했습니다 . 또한 초기 연결에는 약간의 협상이 필요하다는 것이 맞지만 추가 메시지는 그렇지 않습니다.
simonc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.