websocket con éxito la negociación, pero no enviar recibir mensajes correctamente (C# Servidor)

Después de luchar toda la mañana, tengo el apretón de manos para el trabajo, pero ahora estoy atascado en realidad el envío y recepción de mensajes. He estado buscando respuestas en vano así que pensé que finalmente paso hasta aquí y pregunte :/

Mi cliente hasta ahora es muy simple:

function testWebSocket() {
    if (!window.WebSocket) {
        alert('WebSockets are NOT supported by your browser.');
        return;
    }

    try {
        var ws = new WebSocket('ws://localhost:8181/websession');
        ws.onopen = function () {
            alert('Handshake successfully established. Ready for data...');
        };

        ws.onmessage = function (e) {
            alert('Got WebSockets message: ' + e.data);
        }

        ws.onclose = function () {
            alert('Connection closed.');
        };
    }
    catch (e) {
        alert(e);
    }
}

sí, he hecho un montón de código de endeudamiento para este…solo estoy tratando de obtener una prueba de concepto de trabajo con un simple «aplicación de chat»

mi servidor se compone principalmente de dos clases, la SocketServer.cs y el SocketClient.cs

siguen:

SocketServer.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.IO;

namespace WebSocketServer.Entities
{
    class SocketServer
    {
        public static Form1 parentForm;
        TcpListener socketServer;
        public static List<SocketClient> ClientList = new List<SocketClient>();


        public SocketServer(Form1 pForm)
        {

            parentForm = pForm;
            parentForm.ApplyText("Socket Class Initiated\r\n");
            socketServer = new TcpListener(IPAddress.Any, 8181);
            //tell the console that it's started
            parentForm.ApplyText("Socket Server Started\r\n");

            //create continuous loops to listen for new connections
            //start the listener
            socketServer.Start();
            while (true)
            {
                //check for any incoming pending connections
                //create new socket client for new connection
                TcpClient socketConnection = socketServer.AcceptTcpClient();
                DateTime now = DateTime.Now;
                //write message to console to indicate new connection
                parentForm.ApplyText("New Client Connected - " + now.ToString("MM/dd/yyyy h:mm:ss tt") + "\r\n");
                //create new client object for this connection
                SocketClient socketClient = new SocketClient(socketConnection, parentForm);
            }
        }

        public static void CloseClient(SocketClient whichClient)
        {
            ClientList.Remove(whichClient);
            whichClient.Client.Close();
            //dispose of the client object
            whichClient.Dispose();
            whichClient = null;
            parentForm.ApplyText("Client Disconnected\r\n");
        }



        public static void SendTextToClient(SocketClient sc, string text)
        {
            StreamWriter writer = new StreamWriter(sc.Client.GetStream());
            //check if client is still connected, then send the text string
            try
            {
                if (sc.Client.Connected)
                {
                    writer.WriteLine(text);
                    writer.Flush();
                    writer = null;
                }
            }
            catch
            {
                CloseClient(sc);
            }

        }


        public static void SendBroadcast(string text)
        {
            StreamWriter writer;
            //loop through the array and send text to all clients
            foreach (SocketClient client in ClientList)
            {
                if (client.Client.Connected)
                {
                    try
                    {
                        writer = new StreamWriter(client.Client.GetStream());
                        writer.WriteLine(text);
                        writer.Flush();
                        writer = null;

                    }
                    catch
                    {
                        CloseClient(client);
                    }
                }
            }
        }
    }
}

SocketClient.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Security.Cryptography;

namespace WebSocketServer.Entities
{
    class SocketClient
    {
        public TcpClient Client;
        StreamReader reader;
        StreamWriter writer;
        Form1 parentForm;


        public SocketClient(TcpClient client, Form1 pForm)
        {
            parentForm = pForm;
            Client = client;
            Thread clientThread = new Thread(new ThreadStart(StartClient));
            clientThread.Start();
        }


        private void StartClient()
        {
            SocketServer.ClientList.Add(this);
            //create a reader for this client
            reader = new StreamReader(Client.GetStream());
            //create a writer for this client
            writer = new StreamWriter(Client.GetStream());

            var headers = new Dictionary<string, string>();

            string line = "";
            while ((line = reader.ReadLine()) != string.Empty)
            {
                if (!string.IsNullOrEmpty(line))
                {
                    var tokens = line.Split(new char[] { ':' }, 2);
                    if (!string.IsNullOrWhiteSpace(line) && tokens.Length > 1)
                    {
                        headers[tokens[0]] = tokens[1].Trim();
                    }
                }
            }


            String secWebSocketAccept = ComputeWebSocketHandshakeSecurityHash09(headers["Sec-WebSocket-Key"]);

            //send handshake to this client only
            writer.WriteLine("HTTP/1.1 101 Web Socket Protocol Handshake");
            writer.WriteLine("Upgrade: WebSocket");
            writer.WriteLine("Connection: Upgrade");
            writer.WriteLine("WebSocket-Origin: http://localhost:63422/");
            writer.WriteLine("WebSocket-Location: ws://localhost:8181/websession");
            writer.WriteLine("Sec-WebSocket-Accept: " + secWebSocketAccept);
            writer.WriteLine("");
            writer.Flush();

            SocketServer.SendBroadcast("New Client Connected");

            Thread clientRun = new Thread(new ThreadStart(RunClient));
            clientRun.Start();
        }

        public static String ComputeWebSocketHandshakeSecurityHash09(String secWebSocketKey)
         {
             const String MagicKEY = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
             String secWebSocketAccept = String.Empty;

             //1. Combine the request Sec-WebSocket-Key with magic key.
             String ret = secWebSocketKey + MagicKEY;

             //2. Compute the SHA1 hash
             SHA1 sha = new SHA1CryptoServiceProvider(); 
             byte[] sha1Hash = sha.ComputeHash(Encoding.UTF8.GetBytes(ret));

             //3. Base64 encode the hash
             secWebSocketAccept = Convert.ToBase64String(sha1Hash);

             return secWebSocketAccept;
         }


        private void RunClient()
        {
            try
            {
                string line = "";
                while (true)
                {
                    line = reader.ReadLine();
                    if (!string.IsNullOrEmpty(line))
                    {
                        parentForm.ApplyText(line + "\r\n");
                        SocketServer.SendBroadcast(line);
                    }
                }
            }
            catch
            {
                parentForm.ApplyText("Client Disconnected\r\n");
                SocketServer.CloseClient(this);
            }
        }

        public void Dispose()
        {
            System.GC.SuppressFinalize(this);
        }
    }

}

Me puedo conectar con varias instancias en Chrome y mi servidor muestra todos los clientes que se conectan y estoy viendo el aviso de que el apretón de manos fue un éxito. Pero cuando intento enviar el texto desde el cliente (el código no se muestra, pero es bastante sencillo de ws.enviar(texto) un poco la cosa), entra en el servidor como texto ilegible. Cuando intento hacer un escritor.WriteLine(«lo») desde el servidor al cliente, el evento onmessage nunca incendios. He hecho un MONTÓN de mirar a su alrededor después de que finalmente consiguió el apretón de manos ordenados, y no se puede encontrar ningún buen ejemplo de cómo resolver esto.

no debo ser el uso de un StreamWriter? Me estoy perdiendo de algo en mi apretón de manos (un protocolo tal vez).

TIA para observar y ayudar.

Edición:

El siguiente código funciona, pero no sé cómo modificarlo para permitir la dinámica de tamaño de texto de longitud. Yo estoy bien con ser capaz de enviar mensajes de texto que es de 127 o menos en este punto, pero me parece que no puede conseguir una manija en cómo conseguir incluso el pasado 4.

public static void SendBroadcast(string text)
{
    StreamWriter writer;
    //loop through the array and send text to all clients
    foreach (SocketClient client in ClientList)
    {
        if (client.Client.Connected)
        {
            try
            {
                NetworkStream l_Stream = client.Client.GetStream();  
                List<byte> lb = new List<byte>();
                lb.Add(0x81);
                lb.Add(0x04);
                lb.AddRange(Encoding.UTF8.GetBytes("test"));
                l_Stream.Write(lb.ToArray(), 0, 6);
            }
            catch
            {
                CloseClient(client);
            }
        }
    }
}

He intentado modificar lb.Agregar(0x04) a la libra.Agregar(0 x 07) y el envío de «pruebas» no dados. Yo también estoy confundido en cuanto a lo de la l_Stream.Write() parámetros. Sé que es la matriz de bytes, offset, y el tamaño pero el tamaño de la qué?

2 Kommentare

  1. 4

    Mensajes no se envían como texto sin formato en las últimas versiones de la especificación. Ver el sección tramas de datos para más detalles.

    Este wiki post también es muy útil.

    También he escrito un C++ servidor; el WsProtocol80 clase muestra cómo leer/escribir datos.

    EDIT: En el ejemplo de envío de código, el 0x04 byte especifica un 4 bytes del mensaje. Puede establecer valores diferentes y enviar mensajes de hasta 125 bytes de esta manera. Cuando se cambia la longitud del mensaje, también tendría que actualizar el último parámetro a l_Stream.Escribir (que especifica el número de bytes a escribir). El cambio a libras.Contar en todos los casos parece mejor.

    Si sigues encontrando las operaciones bit a bit confuso y más tarde desea enviar más mensajes o leer los mensajes desde el cliente, el enlace de arriba para un wiki post incluye pseudocódigo que debe ser útil.

    • wow eso es muy griego para mí. Terminé siendo capaz de enviar hacia abajo «de prueba» para el cliente por el cambio a una NetworkStream de un StreamWriter y la escritura de una matriz de bytes a partir de una muestra que he encontrado pero es limitado el texto a ser enviado a sólo 4 caracteres (supongo que uno de los valores de byte he añadido a la matriz, provocó que la limitación, pero no sé mucho acerca de bytes et al). Gracias por tu ejemplo de C++, pero yo nunca he mirado nada de C++ antes de lo que no era muy útil. Me gustaría ser capaz de utilizar StreamWriter en lugar de NetworkStream, y estoy tratando de educar mejor a mí mismo en bytes, pero luchando.
    • He actualizado el OP con una edición de lo que yo trabajo para enviar «prueba» al cliente. Cualquier posibilidad de que usted podría proporcionar una idea de mis preguntas en que editar?
    • gracias que fue una gran ayuda. Tengo una pregunta acerca de la generación del valor hexadecimal para agregar a mi matriz de bytes, pero que está fuera del alcance de esta pregunta.
  2. 2

    Tuve el mismo problema, he encontrado la solución:

                lb = new List<byte>();
                lb.Add(0x81);
                size = message.Length;//get the message's size
                lb.Add((byte)size); //get the size in bytes
                lb.AddRange(Encoding.UTF8.GetBytes(message));
                stream.Write(lb.ToArray(), 0, size+2); //I do size+2 because we have 2 bytes plus 0x81 and (byte)size

    Con esta solución, usted puede enviar un mensaje más grande, pero sólo < 127 caracteres

    nota: disculpe, pero mi inglés no es tan bueno. ^^

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Recent Articles

Python «set» con duplicados/elementos repetidos

Hay una forma estándar de representar un "conjunto" que puede contener elementos duplicados. Como yo lo entiendo, un conjunto tiene exactamente un cero o...

Python: generador de expresión vs rendimiento

En Python, ¿hay alguna diferencia entre la creación de un generador de objetos a través de un generador de expresión versus el uso de...

Cómo exportar/importar la Masilla lista de sesiones?

Hay una manera de hacer esto? O tengo que tomar manualmente cada archivo de Registro? InformationsquelleAutor s.webbandit | 2012-10-23

no distingue mayúsculas de minúsculas coincidentes en xpath?

Por ejemplo, para el xml a continuación <CATALOG> <CD title="Empire Burlesque"/> <CD title="empire burlesque"/> <CD...