Création d'un exemple WebSocket «Hello World»

85

Je ne comprends pas pourquoi je ne peux pas faire fonctionner le code suivant. Je souhaite me connecter avec JavaScript à mon application de console serveur. Et puis envoyez des données au serveur.

Voici le code serveur:

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

et voici le 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...");
        };

Lorsque j'exécute ce code, voici ce qui se passe:

Notez que lorsque j'exécute le JavaScript, le serveur accepte et établit avec succès une connexion. JavaScript ne peut cependant pas envoyer de données. Chaque fois que je place la méthode d'envoi, elle n'enverra pas même si une connexion est établie. Comment puis-je faire fonctionner cela?

Tono Nam
la source
9
Cette "question" ne semble plus être une question, et n'est donc pas vraiment adaptée au format de StackOverflow. FWIW, le message du client n'est pas chiffré, il est masqué (obscurci) par XOR'ing contre une valeur aléatoire qui est transmise dans le cadre de la trame. Ce détail de protocole existe pour éviter les attaques d'empoisonnement contre les serveurs proxy qui pourraient mal comprendre le trafic.
EricLaw
1
merci, cette réponse est très utile :) hé, juste une chose, est cette "chaîne privée statique guid =" 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 ";" la chose est toujours constante? sinon, où puis-je obtenir ces valeurs?
Charmie
1
j'ai compris ceci: "Un serveur ne doit masquer aucune
trame
5
Vous auriez probablement dû laisser la question initiale intacte. Le but des questions est de présenter le problème et non la solution. Les réponses, comme vous auriez pu le deviner, concernent les solutions.
Kehlan Krumme
1
Pourquoi l'URL WebSocket se termine-t-elle par «/ service» (ws: // localhost: 8080 / service)? Pourquoi pas simplement «ws: // localhost: 8080»?
andree

Réponses:

72

WebSockets est un protocole qui repose sur une connexion TCP en continu. Bien que WebSockets soit un protocole basé sur les messages.

Si vous souhaitez implémenter votre propre protocole, je vous recommande d'utiliser la dernière spécification stable (pour le 18/04/12) RFC 6455 . Cette spécification contient toutes les informations nécessaires concernant la prise de contact et le cadrage. Ainsi que la plupart des descriptions de scénarios de comportement du côté du navigateur ainsi que du côté du serveur. Il est fortement recommandé de suivre les recommandations concernant le côté serveur lors de la mise en œuvre de votre code.

En quelques mots, je décrirais travailler avec WebSockets comme ceci:

  1. Créez un serveur Socket (System.Net.Sockets) pour le lier à un port spécifique et continuez à écouter avec l'acceptation asynchrone des connexions. Quelque chose comme ca:

    Socket serverSocket = nouveau Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
    serverSocket.Bind (nouveau IPEndPoint (IPAddress.Any, 8080));
    serverSocket.Listen (128);
    serverSocket.BeginAccept (null, 0, OnAccept, null);
  2. Vous devriez avoir la fonction d' acceptation "OnAccept" qui implémentera l'établissement de liaison. À l'avenir, il doit être dans un autre thread si le système est censé gérer une énorme quantité de connexions par seconde.

    private void OnAccept (résultat IAsyncResult) {
    essayez {
        Client de socket = null;
        if (serverSocket! = null && serverSocket.IsBound) {
            client = serverSocket.EndAccept (résultat);
        }
        if (client! = null) {
            / * Prise de contact et gestion de ClientSocket * /
        }
    } catch (exception SocketException) {
    
    } enfin {
        if (serverSocket! = null && serverSocket.IsBound) {
            serverSocket.BeginAccept (null, 0, OnAccept, null);
        }
    }
    }
  3. Une fois la connexion établie, vous devez établir une poignée de main . Basé sur la spécification 1.3 Ouverture de la poignée de main , une fois la connexion établie, vous recevrez une requête HTTP de base avec quelques informations. Exemple:

    GET / chat HTTP / 1.1
    Hôte: server.example.com
    Mise à niveau: websocket
    Connexion: mise à niveau
    Clé Sec-WebSocket: dGhlIHNhbXBsZSBub25jZQ ==
    Origine: http://example.com
    Protocole Sec-WebSocket: chat, superchat
    Version Sec-WebSocket: 13

    Cet exemple est basé sur la version du protocole 13. Gardez à l'esprit que les anciennes versions présentent quelques différences, mais que la plupart des dernières versions sont compatibles entre elles. Différents navigateurs peuvent vous envoyer des données supplémentaires. Par exemple, les détails du navigateur et du système d'exploitation, le cache et autres.

    Sur la base des détails de prise de contact fournis, vous devez générer des lignes de réponse, elles sont pour la plupart identiques, mais contiendront Accpet-Key, qui est basé sur Sec-WebSocket-Key fourni. Dans la spécification 1.3, il est clairement décrit comment générer une clé de réponse. Voici ma fonction que j'utilise pour V13:

    chaîne privée statique guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    chaîne privée AcceptKey (clé de chaîne de référence) {
        string longKey = clé + guid;
        SHA1 sha1 = SHA1CryptoServiceProvider.Create ();
        byte [] hashBytes = sha1.ComputeHash (System.Text.Encoding.ASCII.GetBytes (longKey));
        return Convert.ToBase64String (hashBytes);
    }
    

    La réponse de la poignée de main ressemble à ça:

    Protocoles de commutation HTTP / 1.1 101
    Mise à niveau: websocket
    Connexion: mise à niveau
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK + xOo =

    Mais la clé d'acceptation doit être celle générée en fonction de la clé fournie par le client et de la méthode AcceptKey que j'ai fournie auparavant. De même, assurez-vous qu'après le dernier caractère de la clé d'acceptation, vous mettez deux nouvelles lignes "\ r \ n \ r \ n".

  4. Une fois la réponse de prise de contact envoyée par le serveur, le client doit déclencher la fonction " onopen ", ce qui signifie que vous pouvez envoyer des messages après.
  5. Les messages ne sont pas envoyés au format brut, mais ils ont un cadrage de données . Et du client au serveur, implémentez également le masquage des données basé sur 4 octets fournis dans l'en-tête du message. Bien que du serveur au client, vous n'ayez pas besoin d'appliquer un masquage sur les données. Lisez la section 5. Cadrage des données dans les spécifications. Voici le copier-coller de ma propre implémentation. Ce n'est pas du code prêt à l'emploi, et doit être modifié, je le poste juste pour donner une idée et une logique globale de lecture / écriture avec le cadrage WebSocket. Allez sur ce lien .
  6. Une fois le cadrage mis en œuvre, assurez-vous que vous recevez les données correctement à l'aide de sockets. Par exemple, pour éviter que certains messages ne soient fusionnés en un seul, car TCP est toujours un protocole basé sur le flux. Cela signifie que vous devez lire UNIQUEMENT une quantité spécifique d'octets. La longueur du message est toujours basée sur l'en-tête et les détails de la longueur des données fournis dans l'en-tête lui-même. Ainsi, lorsque vous recevez des données de Socket, recevez d'abord 2 octets, obtenez les détails de l'en-tête en fonction de la spécification de cadrage, puis si le masque a fourni 4 octets supplémentaires, puis la longueur qui peut être de 1, 4 ou 8 octets en fonction de la longueur des données. Et après les données elles-mêmes. Après l'avoir lu, appliquez le démasquage et vos données de message sont prêtes à être utilisées.
  7. Vous voudrez peut-être utiliser un protocole de données , je recommande d'utiliser JSON en raison de l'économie de trafic et facile à utiliser côté client en JavaScript. Pour le côté serveur, vous voudrez peut-être vérifier certains analyseurs. Il y en a beaucoup, google peut être vraiment utile.

La mise en œuvre de son propre protocole WebSockets présente certainement des avantages et une grande expérience, ainsi que le contrôle du protocole lui-même. Mais vous devez passer du temps à le faire et vous assurer que la mise en œuvre est extrêmement fiable.

Dans le même temps, vous pourriez jeter un œil aux solutions prêtes à l'emploi que google a (encore) assez.

moka
la source
Je suppose que je suis coincé sur la poignée de main. quand une nouvelle connexion est reçue, je dois envoyer au client le hachage sha1 de la touche longue plus la touche courte, non?
Tono Nam
J'ai ajouté plus d'informations dans la section 3. Elle décrit plus de détails sur la poignée de main du côté serveur.
moka
1
Assurez-vous également que si des protocoles de requête sont fournis, utilisez-les en réponse pour la ligne Sec-WebSocket-Protocol. Mais seulement s'il est fourni dans la demande. De plus, vous n'avez pas besoin de Version pour la réponse. Et ajoutez un autre NewLine à la fin. Envoyez également toute la chaîne de réponse encodée en UTF8: Encoding.UTF8.GetBytes (responseBytes)
moka
Nous sommes proches. Merci beaucoup pour l'aide. Je suis en mesure d'envoyer un message maintenant, mais le message est crypté je crois. Jetez un œil à mon montage sur lequel je vais bientôt commencer à travailler ...
Tono Nam
Vous devez implémenter le cadrage des données, ce sera je crois le plus compliqué dans la mise en œuvre du protocole WebSockets. J'ajouterai le code copier-coller de mon implémentation dans la publication, mais assurez-vous de le modifier, car il a des choses à changer, mais donne globalement une idée et une logique de travail avec frame.
moka
9

(Réponse publiée au nom du PO) .

Je suis en mesure d'envoyer des données maintenant. C'est ma nouvelle version du programme grâce à vos réponses et au code de @Maksims Mihejevs.

Serveur

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>

Lorsque j'exécute ce code, je suis capable d'envoyer et de recevoir des données à la fois du client et du serveur. Le seul problème est que les messages sont chiffrés lorsqu'ils arrivent sur le serveur. Voici les étapes de fonctionnement du programme:

entrez la description de l'image ici

Notez comment le message du client est chiffré.

licol
la source
2
Quelque chose ne va pas avec votre exemple, lorsque j'appuie sur Entrée, la connexion est fermée.
Richard Aguirre
@RichardAguirre: J'ai posté ceci au nom du PO (voir la première ligne de la réponse) - actuellement, ils ne seront pas informés de votre message. Vous pouvez essayer de leur envoyer un ping sous la question, mais ils auront probablement besoin de beaucoup plus de détails que cela.
halfer
6

Les WebSockets sont implémentés avec un protocole qui implique une négociation entre le client et le serveur . Je n'imagine pas qu'ils fonctionnent beaucoup comme des prises normales. Renseignez-vous sur le protocole et demandez à votre application d'en parler. Vous pouvez également utiliser une bibliothèque WebSocket existante ou .Net4.5beta qui possède une API WebSocket .

dépensier
la source
Bien sûr, ils fonctionnent très bien comme des prises normales. Le socket est à un niveau inférieur au protocole d'application et, en tant que tel, n'en dépend pas. Cela signifie que vous pouvez exécuter FTP, SMTP, HTTP, WebSockets, etc ... sur une socket. C'est à l'implémenteur de s'assurer qu'elle suit correctement le protocole ou personne ne pourra parler au serveur.
SRM
4

Je n'ai pas trouvé d'exemple de travail simple nulle part (au 19 janvier), voici donc une version mise à jour. J'ai la version chrome 71.0.3578.98.

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

Client html et 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
la source
3

Problème

Puisque vous utilisez WebSocket, Spender est correct. Après avoir reçu les données initiales du WebSocket, vous devez envoyer le message de prise de contact du serveur C # avant que d'autres informations puissent circuler.

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

Quelque chose de ce genre.

Vous pouvez faire des recherches supplémentaires sur le fonctionnement de WebSocket sur w3 ou google.

Liens et ressources

Voici une spécifcation de protocole: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76#section-1.3

Liste d'exemples de travail:

caesay
la source
J'utilise également l'encodage UTF8. Dois-je en utiliser un autre tel que ASCII?
Tono Nam
@TonoNam: Autant que je sache, l'encodage UTF8 est correct - bien que je ne sois pas un expert HTML5, donc je ne sais pas avec certitude.
caesay
Je l'ai fait fonctionner avec safari !!! J'en ai besoin pour le faire fonctionner avec Google Chrome. Tous les exemples se connectent mais aucun d'entre eux ne parvient à envoyer des données. Je vais continuer à essayer. Merci beaucoup pour l'aide!
Tono Nam
Bien sûr ... Si je ne le fais toujours pas fonctionner, je ferai de cette question une question de prime! Je suis vraiment curieux de voir cela fonctionner. Merci pour l'aide
Tono Nam
Votre lien de spécification de protocole est obsolète. Safari l'utilise toujours mais d'autres navigateurs sont passés à la RFC 6455 incompatible . De plus, même si vous avez raison de dire que la connexion initiale nécessite une négociation, les autres messages ne le font pas.
simonc