Erstellen eines WebSocket-Beispiels für "Hello World"

84

Ich verstehe nicht, warum ich den folgenden Code nicht zum Laufen bringen kann. Ich möchte mit JavaScript eine Verbindung zu meiner Serverkonsolenanwendung herstellen. Und dann senden Sie Daten an den Server.

Hier ist der Servercode:

    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));
        }
    }

und hier ist das 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...");
        };

Wenn ich diesen Code ausführe, passiert Folgendes:

Beachten Sie, dass der Server beim Ausführen von JavaScript eine Verbindung akzeptiert und erfolgreich herstellt. JavaScript kann jedoch keine Daten senden. Immer wenn ich die Sendemethode platziere, wird sie nicht gesendet, obwohl eine Verbindung hergestellt wurde. Wie kann ich das zum Laufen bringen?

Tono Nam
quelle
9
Diese "Frage" scheint keine Frage mehr zu sein und ist daher nicht wirklich für das Format von StackOverflow geeignet. FWIW, die Nachricht des Clients wird nicht verschlüsselt, sondern durch XOR'ing gegen einen zufälligen Wert maskiert (verschleiert), der als Teil des Frames übertragen wird. Dieses Protokolldetail dient dazu, Vergiftungsangriffe auf Proxyserver zu vermeiden, die den Datenverkehr missverstehen könnten.
EricLaw
1
danke, diese Antwort ist sehr hilfreich :) hey, nur eine Sache, ist diese "statische private Zeichenfolge guid =" 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 ";" was ist immer konstant? Wenn nicht, wo kann ich diese Werte erhalten?
Charmie
1
Ich habe folgendes: "Ein Server darf keine Frames maskieren, die er an den Client sendet"
Charmie
5
Sie hätten wahrscheinlich die ursprüngliche Frage intakt lassen sollen. Der Zweck der Fragen besteht darin, das Problem darzustellen, nicht die Lösung. Die Antworten sind, wie Sie hätten erraten können, für die Lösungen.
Kehlan Krumme
1
Warum endet die WebSocket-URL mit '/ service' (ws: // localhost: 8080 / service)? Warum nicht einfach 'ws: // localhost: 8080'?
andree

Antworten:

70

WebSockets ist ein Protokoll, das auf einer TCP-Streaming-Verbindung basiert. Obwohl WebSockets ein nachrichtenbasiertes Protokoll ist.

Wenn Sie Ihr eigenes Protokoll implementieren möchten, empfehle ich die Verwendung der neuesten und stabilsten Spezifikation (für 18/04/12) RFC 6455 . Diese Spezifikation enthält alle erforderlichen Informationen zu Handshake und Framing. Ebenso die meisten Beschreibungen zu Szenarien des Verhaltens sowohl von der Browserseite als auch von der Serverseite. Es wird dringend empfohlen, bei der Implementierung Ihres Codes die Empfehlungen zur Serverseite zu befolgen.

In wenigen Worten würde ich die Arbeit mit WebSockets folgendermaßen beschreiben:

  1. Erstellen Sie einen Server-Socket (System.Net.Sockets), binden Sie ihn an einen bestimmten Port und überwachen Sie die asynchrone Annahme von Verbindungen. Sowas in der Art:

    Socket serverSocket = neuer Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
    serverSocket.Bind (neuer IPEndPoint (IPAddress.Any, 8080));
    serverSocket.Listen (128);
    serverSocket.BeginAccept (null, 0, OnAccept, null);
  2. Sie sollten die Akzeptanzfunktion "OnAccept" haben, die den Handshake implementiert. In Zukunft muss es sich in einem anderen Thread befinden, wenn das System eine große Anzahl von Verbindungen pro Sekunde verarbeiten soll.

    private void OnAccept (IAsyncResult-Ergebnis) {
    Versuchen {
        Socket-Client = null;
        if (serverSocket! = null && serverSocket.IsBound) {
            client = serverSocket.EndAccept (Ergebnis);
        }}
        if (client! = null) {
            / * Handshake und Verwalten von ClientSocket * /
        }}
    } catch (SocketException-Ausnahme) {
    
    } schließlich {
        if (serverSocket! = null && serverSocket.IsBound) {
            serverSocket.BeginAccept (null, 0, OnAccept, null);
        }}
    }}
    }}
  3. Nachdem die Verbindung hergestellt wurde, müssen Sie einen Handshake durchführen . Basierend auf Spezifikation 1.3 Opening Handshake erhalten Sie nach dem Herstellen der Verbindung eine grundlegende HTTP-Anfrage mit einigen Informationen. Beispiel:

    GET / chat HTTP / 1.1
    Host: server.example.com
    Upgrade: Websocket
    Verbindung: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ ==
    Herkunft: http://example.com
    Sec-WebSocket-Protokoll: Chat, Superchat
    Sec-WebSocket-Version: 13

    Dieses Beispiel basiert auf der Version von Protokoll 13. Beachten Sie, dass ältere Versionen einige Unterschiede aufweisen, die meisten neuesten Versionen jedoch kreuzkompatibel sind. Verschiedene Browser senden Ihnen möglicherweise zusätzliche Daten. Zum Beispiel Browser- und Betriebssystemdetails, Cache und andere.

    Basierend auf den bereitgestellten Handshake-Details müssen Sie Antwortzeilen generieren. Diese sind größtenteils identisch, enthalten jedoch den Accpet-Key, der auf dem bereitgestellten Sec-WebSocket-Key basiert. In Spezifikation 1.3 wird klar beschrieben, wie ein Antwortschlüssel generiert wird. Hier ist meine Funktion, die ich für V13 verwendet habe:

    statische private Zeichenfolge guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    private Zeichenfolge AcceptKey (Referenzzeichenfolgenschlüssel) {
        Zeichenfolge longKey = Schlüssel + Guid;
        SHA1 sha1 = SHA1CryptoServiceProvider.Create ();
        byte [] hashBytes = sha1.ComputeHash (System.Text.Encoding.ASCII.GetBytes (longKey));
        return Convert.ToBase64String (hashBytes);
    }}
    

    Die Handshake-Antwort sieht so aus:

    HTTP / 1.1 101 Switching-Protokolle
    Upgrade: Websocket
    Verbindung: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK + xOo =

    Der Akzeptanzschlüssel muss jedoch der generierte sein, der auf dem vom Client bereitgestellten Schlüssel und der zuvor von mir bereitgestellten Methode AcceptKey basiert. Stellen Sie außerdem sicher, dass Sie nach dem letzten Zeichen der Akzeptiertaste zwei neue Zeilen "\ r \ n \ r \ n" einfügen.

  4. Nachdem die Handshake-Antwort vom Server gesendet wurde, sollte der Client die Funktion " onopen " auslösen. Dies bedeutet, dass Sie Nachrichten nach dem Senden senden können.
  5. Nachrichten werden nicht im Rohformat gesendet, haben jedoch einen Datenrahmen . Und von Client zu Server implementieren Sie auch die Maskierung für Daten basierend auf den bereitgestellten 4 Bytes im Nachrichtenkopf. Obwohl Sie vom Server zum Client keine Maskierung auf Daten anwenden müssen. Lesen Sie Abschnitt 5. Datenrahmen in der Spezifikation. Hier ist Copy-Paste aus meiner eigenen Implementierung. Es ist kein gebrauchsfertiger Code und muss geändert werden. Ich veröffentliche ihn nur, um eine Vorstellung und eine allgemeine Logik des Lesens / Schreibens mit WebSocket-Framing zu vermitteln. Gehen Sie zu diesem Link .
  6. Stellen Sie nach der Implementierung des Framings sicher, dass Sie die Daten mithilfe von Sockets richtig empfangen. Zum Beispiel, um zu verhindern, dass einige Nachrichten zu einer zusammengeführt werden, da TCP immer noch ein Stream-basiertes Protokoll ist. Das bedeutet, dass Sie NUR eine bestimmte Anzahl von Bytes lesen müssen. Die Länge der Nachricht basiert immer auf dem Header und den Angaben zur Datenlänge im Header. Wenn Sie also Daten von Socket empfangen, empfangen Sie zuerst 2 Bytes, erhalten Sie Details aus dem Header basierend auf der Framing-Spezifikation. Wenn die Maske weitere 4 Bytes bereitstellt, kann die Länge je nach Datenlänge 1, 4 oder 8 Bytes betragen. Und nach Daten selbst. Wenden Sie nach dem Lesen die Demaskierung an und Ihre Nachrichtendaten sind einsatzbereit.
  7. Sie könnten einige verwenden möchten Data Protocol , empfehle ich JSON wegen Verkehrswirtschaft zu bedienen und leicht zu bedienen auf Client - Seite in JavaScript. Auf der Serverseite möchten Sie möglicherweise einige Parser überprüfen. Es gibt viele davon, Google kann wirklich hilfreich sein.

Die Implementierung eines eigenen WebSockets-Protokolls hat definitiv einige Vorteile und großartige Erfahrungen sowie die Kontrolle über das Protokoll selbst. Sie müssen jedoch einige Zeit damit verbringen und sicherstellen, dass die Implementierung äußerst zuverlässig ist.

Gleichzeitig können Sie sich gebrauchsfertige Lösungen ansehen, die Google (wieder) bietet.

Moka
quelle
Ich glaube, ich stecke beim Händeschütteln fest. Wenn eine neue Verbindung empfangen wird, muss ich den sha1-Hash des langen Schlüssels plus des kurzen Schlüssels an den Client senden, oder?
Tono Nam
Ich habe in Abschnitt 3 weitere Informationen hinzugefügt. Hier werden weitere Details zum Handshake von der Serverseite aus beschrieben.
Moka
1
Stellen Sie außerdem sicher, dass bei Bereitstellung von Anforderungsprotokollen diese als Antwort für die Sec-WebSocket-Protocol-Leitung verwendet werden. Aber nur wenn es auf Anfrage zur Verfügung gestellt wird. Außerdem benötigen Sie keine Version für die Antwort. Und fügen Sie am Ende eine weitere NewLine hinzu. Senden Sie auch die gesamte Antwortzeichenfolge, die mit UTF8 codiert wurde: Encoding.UTF8.GetBytes (responseBytes)
moka
Wir sind nah. Vielen Dank für die Hilfe. Ich kann jetzt eine Nachricht senden, aber die Nachricht ist meines Erachtens verschlüsselt. Schauen Sie sich meine Bearbeitung an, an der ich bald arbeiten werde ...
Tono Nam
Sie müssen Data Framing implementieren. Dies ist meines Erachtens das komplizierteste Bit bei der Implementierung des WebSockets-Protokolls. Ich werde Copy-Paste-Code aus meiner Implementierung in den Post einfügen, aber stellen Sie sicher, dass Sie ihn bearbeiten, da er einige Dinge zu ändern hat, aber insgesamt eine Idee und Logik für die Arbeit mit Frame vermittelt.
Moka
9

(Antwort im Namen des OP veröffentlicht) .

Ich kann jetzt Daten senden. Dies ist meine neue Version des Programms dank Ihrer Antworten und des Codes von @Maksims Mihejevs.

Server

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));
        }
    }
}

JavaScript:

<!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>

Wenn ich diesen Code ausführe, kann ich Daten sowohl vom Client als auch vom Server senden und empfangen. Das einzige Problem ist, dass die Nachrichten verschlüsselt werden, wenn sie auf dem Server ankommen. Hier sind die Schritte zur Ausführung des Programms:

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, wie die Nachricht vom Client verschlüsselt wird.

halfer
quelle
2
Mit Ihrem Beispiel stimmt etwas nicht. Wenn ich die Eingabetaste drücke, wird die Verbindung geschlossen.
Richard Aguirre
@RichardAguirre: Ich habe dies im Namen des OP gepostet (siehe die erste Zeile der Antwort) - derzeit werden sie nicht über Ihre Nachricht informiert. Sie könnten versuchen, sie unter die Frage zu pingen, aber sie benötigen wahrscheinlich viel mehr Details.
Halfer
6

WebSockets werden mit einem Protokoll implementiert , das einen Handshake zwischen Client und Server beinhaltet . Ich kann mir nicht vorstellen, dass sie wie normale Steckdosen funktionieren. Informieren Sie sich über das Protokoll und lassen Sie Ihre Anwendung darüber sprechen. Verwenden Sie alternativ eine vorhandene WebSocket-Bibliothek oder .Net4.5beta mit einer WebSocket-API .

Spender
quelle
Natürlich funktionieren sie sehr ähnlich wie normale Steckdosen. Der Socket befindet sich auf einer niedrigeren Ebene als das Anwendungsprotokoll und ist daher nicht davon abhängig. Das heißt, Sie können FTP, SMTP, HTTP, WebSockets usw. auf einem Socket ausführen. Es ist Sache des Implementierers, sicherzustellen, dass er das Protokoll korrekt befolgt, da sonst niemand mit dem Server sprechen kann.
SRM
4

Ich konnte nirgendwo ein einfaches Arbeitsbeispiel finden (Stand: 19. Januar), daher hier eine aktualisierte Version. Ich habe Chrome Version 71.0.3578.98.

C # Websocket-Server:

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;
    }
}
}

Client HTML und Javascript:

<!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>

Deepak Garud
quelle
3

Problem

Da Sie WebSocket verwenden, ist spender korrekt. Nachdem Sie die anfänglichen Daten vom WebSocket erhalten haben, müssen Sie die Handshake-Nachricht vom C # -Server senden, bevor weitere Informationen fließen können.

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

Etwas in diese Richtung.

Sie können weitere Untersuchungen zur Funktionsweise von WebSocket unter w3 oder google durchführen.

Links und Ressourcen

Hier ist eine Protokollspezifikation: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76#section-1.3

Liste der Arbeitsbeispiele:

Caesay
quelle
Außerdem verwende ich die UTF8-Codierung. Sollte ich ein anderes wie ASCII verwenden?
Tono Nam
@TonoNam: Soweit ich weiß, ist die UTF8-Codierung korrekt - obwohl ich kein HTML5-Experte bin, weiß ich es nicht genau.
Caesay
Ich habe es mit Safari geschafft !!! Ich brauche es, damit es mit Google Chrome funktioniert. Alle Beispiele verbinden sich, aber keines von ihnen sendet erfolgreich Daten. Ich werde es weiter versuchen. Vielen Dank für die Hilfe!
Tono Nam
Natürlich ... Wenn ich es immer noch nicht zum Laufen bringe, mache ich aus dieser Frage eine Kopfgeldfrage! Ich bin wirklich neugierig, dass dies funktioniert. Vielen Dank für die Hilfe
Tono Nam
Ihr Protokollspezifikationslink ist veraltet. Safari verwendet dies weiterhin, aber andere Browser haben auf den inkompatiblen RFC 6455 umgestellt . Auch wenn Sie richtig sind, dass die anfängliche Verbindung einige Verhandlungen erfordert, sind dies bei weiteren Nachrichten nicht der Fall.
Simonc