简体   繁体   中英

C# websocket server receive text from javascript

I am currently testing some basic websocket examples that aren't completely helping me with the basics. I understand how to create a listener on the server with C#, and to upgrade the request to be a web socket. I need help retrieving a string sent from javascript into the server.

C# Code:

class Program
{
    private static void ThreadProc(object obj)
    {
        var client = (TcpClient)obj;

        var address = client.Client.RemoteEndPoint.ToString().Split(':');

        Console.WriteLine(String.Format("A client is connected from {0}", address[0]));

        NetworkStream stream = client.GetStream();

        //enter to an infinite cycle to be able to handle every change in stream
        while (true)
        {
            while (!stream.DataAvailable) ;

            Byte[] bytes = new Byte[client.Available];

            stream.Read(bytes, 0, bytes.Length);

            //translate bytes of request to string
            String data = Encoding.UTF8.GetString(bytes);

            if (new Regex("^GET").IsMatch(data))
            {
                Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + Environment.NewLine
                    + "Connection: Upgrade" + Environment.NewLine
                    + "Upgrade: websocket" + Environment.NewLine
                    + "Sec-WebSocket-Accept: " + Convert.ToBase64String(
                        SHA1.Create().ComputeHash(
                            Encoding.UTF8.GetBytes(
                                new Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
                            )
                        )
                    ) + Environment.NewLine
                    + Environment.NewLine);

                stream.Write(response, 0, response.Length);
            }
            else
            {
                Console.WriteLine(data);
            }
        }
    }

    static void Main(string[] args)
    {
        TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);

        server.Start();
        Console.WriteLine("Server has started on 127.0.0.1:80.{0}Waiting for a connection...", Environment.NewLine);

        while (true)
        {
            var clientConnection = server.AcceptTcpClient();
            ThreadPool.QueueUserWorkItem(ThreadProc, clientConnection);
        }

    }
}

Javascript for connecting to websocket.

var host = window.location.origin.replace("http", "ws");
    var socket = new WebSocket("ws://127.0.0.1:80");

    socket.onopen = function (openEvent) {
        console.log("Socket connection is open.");
        sendTextMessage();
    };

    function sendTextMessage() {
        if (socket.readyState != WebSocket.OPEN)
        {
            console.log("Socket is not open for connection.");
            return;
        }
        socket.send("MDN");
    }

Update I can see the message coming in now. However, I don't get the string MDN I get some funky characters back. Updated my C# code to show changes.

I am just simply trying to send a string from my javascript into my server and read that string out on the console. If anyone can explain even more how to have multiple web browsers connected in at the same time that would be awesome. Also if anyone can point me towards sending messages back to all connected web browsers please do.

If this is a duplicate please point me in the right direction.

Question : "multiple web browsers connected in at the same time"

while(serverIsOn){
    TcpClient cliTemp = server.AcceptTcpClient();
    NetworkStream netTemp = cliTemp.GetStream(); 
    Client cli = new Client(Necessary attributes);
    clientsList.Add(cli);
}

every time you get one connection put every attribute in a new object (create class Client) with the attributes necessary to respond/receive from that client example(TcpClient, NetworkStream, clientName...)

[Another Thread] New loop through the clients list and before calling Read:

loop(clientsList)

 if(cli.networkStream.DataAvailable){ cli.networkStream.Read(buffer, 0, buffer.Lenght); } 

Question "Update I can see the message coming in now. However, I don't get the string MDN I get some funky characters back. Updated my C# code to show changes." I suppose you were following this tutorial https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_server

It says the message response from JavaScript contains certain bits that indicate if the message is final how long is the message and a key code to decode the message here's a small solution:

public byte[] javaScriptUser(Byte[] data)
    {
        //encoded[1] => size of msg
        Byte[] encoded = new Byte[((int)data[1] - 128)];
        Array.Copy(data, 6, encoded, 0, encoded.Length);
        Byte[] decoded = new Byte[((int)data[1] - 128)]; 

        //KeyCode positions
        Byte[] key = new Byte[4] { data[2], data[3], data[4], data[5] };

        for (int i = 0; i < encoded.Length; i++)
        {
            decoded[i] = (Byte)(encoded[i] ^ key[i % 4]);
        }
        Array.Copy(decoded, data, decoded.Length);
        return decoded;
    }

does not include this part! ("If it is 126, the following 2 bytes (16-bit unsigned integer), if 127, the following 8 bytes (64-bit unsigned integer) are the length.") This last part is a bit messy was done in a couple of minutes but I'm sure you can make it better

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM