Creación de un ejemplo de WebSocket "Hola mundo"

85

No entiendo por qué no puedo hacer que el siguiente código funcione. Quiero conectarme con JavaScript a la aplicación de mi consola de servidor. Y luego envía datos al servidor.

Aquí está el código del servidor:

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

y aquí está el 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...");
        };

Cuando ejecuto ese código, esto es lo que sucede:

Tenga en cuenta que cuando ejecuto JavaScript, el servidor acepta y establece correctamente una conexión. Sin embargo, JavaScript no puede enviar datos. Siempre que coloco el método de envío, no enviará aunque se establezca una conexión. ¿Cómo puedo hacer que esto funcione?

Tono Nam
fuente
9
Esta "pregunta" ya no parece ser una pregunta y, por lo tanto, no se adapta realmente al formato de StackOverflow. FWIW, el mensaje del cliente no está encriptado , está enmascarado (ofuscado) por XOR'ing contra un valor aleatorio que se transmite como parte del marco. Este detalle del protocolo existe para evitar ataques de envenenamiento contra servidores proxy que podrían malinterpretar el tráfico.
EricLaw
1
gracias, esta respuesta es muy útil :) hey, solo una cosa, es esta "cadena privada estática guid =" 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 ";" la cosa es siempre constante? si no es así, ¿dónde puedo obtener estos valores?
Charmie
1
Recibí esto: "Un servidor no debe enmascarar ningún marco que envíe al cliente"
Charmie
5
Probablemente debería haber dejado intacta la pregunta original. El propósito de las preguntas es presentar el problema, no la solución. Las respuestas, como habrás adivinado, son para las soluciones.
Kehlan Krumme
1
¿Por qué la URL de WebSocket termina con '/ service' (ws: // localhost: 8080 / service)? ¿Por qué no solo 'ws: // localhost: 8080'?
andree

Respuestas:

72

WebSockets es un protocolo que se basa en una conexión por streaming TCP. Aunque WebSockets es un protocolo basado en mensajes.

Si desea implementar su propio protocolo, le recomiendo utilizar la especificación más reciente y estable (para el 18/04/12) RFC 6455 . Esta especificación contiene toda la información necesaria sobre el protocolo de enlace y el encuadre. Además de la mayor parte de la descripción sobre escenarios de comportamiento desde el lado del navegador y desde el lado del servidor. Es muy recomendable seguir las recomendaciones sobre el lado del servidor durante la implementación de su código.

En pocas palabras, describiría trabajar con WebSockets así:

  1. Cree un socket de servidor (System.Net.Sockets), vincúlelo a un puerto específico y siga escuchando con la aceptación asíncrona de conexiones. Algo como eso:

    Socket serverSocket = nuevo Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
    serverSocket.Bind (nuevo IPEndPoint (IPAddress.Any, 8080));
    serverSocket.Listen (128);
    serverSocket.BeginAccept (nulo, 0, OnAccept, nulo);
  2. Debería tener la función de aceptación "OnAccept" que implementará el protocolo de enlace. En el futuro, tendrá que estar en otro hilo si el sistema está destinado a manejar una gran cantidad de conexiones por segundo.

    Private void OnAccept (resultado de IAsyncResult) {
    tratar {
        Cliente de socket = nulo;
        if (serverSocket! = null && serverSocket.IsBound) {
            cliente = serverSocket.EndAccept (resultado);
        }
        if (cliente! = nulo) {
            / * Apretón de manos y gestión de ClientSocket * /
        }
    } catch (excepción de SocketException) {
    
    } finalmente {
        if (serverSocket! = null && serverSocket.IsBound) {
            serverSocket.BeginAccept (nulo, 0, OnAccept, nulo);
        }
    }
    }
  3. Una vez establecida la conexión, debe realizar un apretón de manos . Según la especificación 1.3 Apertura del protocolo de enlace, una vez establecida la conexión, recibirá una solicitud HTTP básica con cierta información. Ejemplo:

    OBTENER / chat HTTP / 1.1
    Host: servidor.ejemplo.com
    Actualización: websocket
    Conexión: actualización
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ ==
    Origen: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Versión: 13

    Este ejemplo se basa en la versión del protocolo 13. Tenga en cuenta que las versiones anteriores tienen algunas diferencias, pero la mayoría de las versiones más recientes son compatibles entre sí. Es posible que diferentes navegadores le envíen algunos datos adicionales. Por ejemplo, detalles del navegador y del sistema operativo, caché y otros.

    Según los detalles del protocolo de enlace proporcionados, debe generar líneas de respuesta, en su mayoría son iguales, pero contendrán Accpet-Key, que se basa en Sec-WebSocket-Key proporcionado. En la especificación 1.3 se describe claramente cómo generar la clave de respuesta. Aquí está mi función que he estado usando para V13:

    cadena privada estática guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    cadena privada AcceptKey (clave de cadena de referencia) {
        cadena longKey = clave + guid;
        SHA1 sha1 = SHA1CryptoServiceProvider.Create ();
        byte [] hashBytes = sha1.ComputeHash (System.Text.Encoding.ASCII.GetBytes (longKey));
        return Convert.ToBase64String (hashBytes);
    }
    

    La respuesta del apretón de manos se ve así:

    HTTP / 1.1 101 protocolos de conmutación
    Actualización: websocket
    Conexión: actualización
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK + xOo =

    Pero la clave de aceptación tiene que ser la generada según la clave proporcionada por el cliente y el método AcceptKey que proporcioné antes. Además, asegúrese de que después del último carácter de la tecla de aceptación ponga dos líneas nuevas "\ r \ n \ r \ n".

  4. Después de que se envía la respuesta del protocolo de enlace desde el servidor, el cliente debe activar la función " onopen ", lo que significa que puede enviar mensajes después.
  5. Los mensajes no se envían en formato sin procesar, pero tienen Data Framing . Y desde el cliente al servidor, también implemente el enmascaramiento de los datos según los 4 bytes proporcionados en el encabezado del mensaje. Aunque de servidor a cliente no es necesario aplicar enmascaramiento sobre los datos. Lea la sección 5. Encuadre de datos en la especificación. Aquí está copiar y pegar de mi propia implementación. No es un código listo para usar y debe modificarse, lo estoy publicando solo para dar una idea y la lógica general de lectura / escritura con el marco de WebSocket. Vaya a este enlace .
  6. Una vez implementado el encuadre, asegúrese de recibir los datos de forma correcta mediante sockets. Por ejemplo, para evitar que algunos mensajes se fusionen en uno solo, porque TCP sigue siendo un protocolo basado en flujo. Eso significa que debe leer SOLO una cantidad específica de bytes. La longitud del mensaje siempre se basa en el encabezado y los detalles de longitud de datos proporcionados en el encabezado. Entonces, cuando reciba datos de Socket, primero reciba 2 bytes, obtenga detalles del encabezado según la especificación de encuadre, luego, si la máscara proporcionó otros 4 bytes, y luego la longitud podría ser 1, 4 u 8 bytes según la longitud de los datos. Y después de los datos en sí. Después de leerlo, aplique desenmascaramiento y los datos de su mensaje estarán listos para usar.
  7. Es posible que desee utilizar algún protocolo de datos , recomiendo utilizar JSON debido a la economía de tráfico y fácil de usar en el lado del cliente en JavaScript. Para el lado del servidor, es posible que desee verificar algunos de los analizadores. Hay muchos, google puede ser muy útil.

La implementación del propio protocolo WebSockets definitivamente tiene algunos beneficios y una gran experiencia que obtiene, así como el control sobre el protocolo en sí. Pero debe dedicar algo de tiempo a hacerlo y asegurarse de que la implementación sea altamente confiable.

Al mismo tiempo, es posible que eche un vistazo a las soluciones listas para usar que Google (nuevamente) tiene suficientes.

moka
fuente
Supongo que estoy atrapado en el apretón de manos. cuando se recibe una nueva conexión, tengo que enviar al cliente el hash sha1 de la clave larga más la clave corta, ¿verdad?
Tono Nam
Agregué más información en la sección 3. Describe más detalles sobre el protocolo de enlace desde el lado del servidor.
moka
1
Además, asegúrese de que si se proporcionan protocolos de solicitud, use el mismo en respuesta para la línea Sec-WebSocket-Protocol. Pero solo si se proporciona en la solicitud. Además, no necesita la versión para responder. Y agregue otra NewLine al final. También envíe la cadena de respuesta completa codificada con UTF8: Encoding.UTF8.GetBytes (responseBytes)
moka
Estamos cerca. Muchísimas gracias por la ayuda. Puedo enviar un mensaje ahora, pero creo que el mensaje está encriptado. Echa un vistazo a mi edición en la que empezaré a trabajar pronto ...
Tono Nam
Debe implementar el encuadre de datos, creo que esto será lo más complicado en la implementación del protocolo WebSockets. Agregaré el código de copiar y pegar de mi implementación en la publicación, pero asegúrese de editarlo, porque tiene algunas cosas que cambiar, pero en general da una idea y la lógica de trabajar con frame.
moka
9

(Respuesta publicada en nombre del OP) .

Ahora puedo enviar datos. Esta es mi nueva versión del programa gracias a tus respuestas y al código de @Maksims Mihejevs.

Servidor

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>

Cuando ejecuto ese código, puedo enviar y recibir datos tanto del cliente como del servidor. El único problema es que los mensajes están encriptados cuando llegan al servidor. Estos son los pasos de cómo se ejecuta el programa:

ingrese la descripción de la imagen aquí

Tenga en cuenta cómo se cifra el mensaje del cliente.

halfer
fuente
2
Algo está mal con su ejemplo, cuando presiono enter, la conexión se cierra.
Richard Aguirre
@RichardAguirre: Publiqué esto en nombre del OP (ver la primera línea de la respuesta); actualmente no se les notificará su mensaje. Puede intentar hacerles ping debajo de la pregunta, pero es probable que necesiten muchos más detalles que eso.
Halfer
6

Los WebSockets se implementan con un protocolo que implica un protocolo de enlace entre el cliente y el servidor . No creo que funcionen de forma muy parecida a los enchufes normales. Lea sobre el protocolo y obtenga su aplicación para hablarlo. Alternativamente, use una biblioteca WebSocket existente o .Net4.5beta que tenga una API WebSocket .

gastador
fuente
Por supuesto, funcionan de manera muy similar a los enchufes normales. El socket está en un nivel más bajo que el protocolo de aplicación y, como tal, no depende de él. Eso significa que puede ejecutar FTP, SMTP, HTTP, WebSockets, etc ... en un socket. Depende del implementador asegurarse de que sigue el protocolo correctamente o nadie podrá hablar con el servidor.
SRM
4

No pude encontrar un ejemplo de trabajo simple en ninguna parte (a partir del 19 de enero), así que aquí hay una versión actualizada. Tengo la versión de Chrome 71.0.3578.98.

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

Cliente html y 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
fuente
3

Problema

Dado que está utilizando WebSocket, el gastador es correcto. Después de recibir los datos iniciales de WebSocket, debe enviar el mensaje de reconocimiento desde el servidor C # antes de que pueda fluir más información.

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

Algo en ese sentido.

Puede investigar más sobre cómo funciona WebSocket en w3 o google.

Enlaces y recursos

Aquí hay una especifcación de protocolo: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76#section-1.3

Lista de ejemplos de trabajo:

Caesay
fuente
También estoy usando codificación UTF8. ¿Debería usar uno diferente como ASCII?
Tono Nam
@TonoNam: Hasta donde yo sé, la codificación UTF8 es correcta, aunque no soy un experto en HTML5, así que no lo sé con certeza.
Caesay
¡Lo hice funcionar con safari! Sin embargo, lo necesito para que funcione con Google Chrome. Todos los ejemplos se conectan, pero ninguno envía datos correctamente. Seguiré intentando. ¡Muchas gracias por la ayuda!
Tono Nam
Por supuesto ... ¡Si todavía no lo hago funcionar, convertiré esta pregunta en una recompensa! Tengo mucha curiosidad por ver que esto funcione. Gracias por la ayuda
Tono Nam
Su enlace de especificación de protocolo está desactualizado. Safari todavía usa esto, pero otros navegadores han pasado al incompatible RFC 6455 . Además, aunque tiene razón en que la conexión inicial requiere algo de negociación, los mensajes posteriores no.
simonc