예제 #1
0
        internal static async Task ReceiveAndReplyClientMessage(TcpClient clientWssAccepted, NetworkStream clientStream, byte[] wssReceivedBytes, HttpRequest firstRequestOfHandShake)
        {
            bool fin  = (wssReceivedBytes[0] & 0b10000000) != 0;
            bool mask = (wssReceivedBytes[1] & 0b10000000) != 0; // must be true, "All messages from the client to the server have this bit set"

            int opcode = wssReceivedBytes[0] & 0b00001111,       // expecting 1 - text message
                msglen = wssReceivedBytes[1] - 128,              // & 0111 1111
                offset = 2;

            if (msglen == 126)
            {
                // was ToUInt16(bytes, offset) but the result is incorrect
                msglen = BitConverter.ToUInt16(new byte[] { wssReceivedBytes[3], wssReceivedBytes[2] }, 0);
                offset = 4;
            }
            else if (msglen == 127)
            {
                Console.WriteLine("TODO: msglen == 127, needs qword to store msglen");
                // i don't really know the byte order, please edit this
                // msglen = BitConverter.ToUInt64(new byte[] { bytes[5], bytes[4], bytes[3], bytes[2], bytes[9], bytes[8], bytes[7], bytes[6] }, 0);
                // offset = 10;
            }

            if (msglen == 0)
            {
                Console.WriteLine("msglen == 0");
            }
            else if (mask)
            {
                byte[] decoded = new byte[msglen];
                byte[] masks   = new byte[4] {
                    wssReceivedBytes[offset], wssReceivedBytes[offset + 1], wssReceivedBytes[offset + 2], wssReceivedBytes[offset + 3]
                };
                offset += 4;

                for (int i = 0; i < msglen; ++i)
                {
                    decoded[i] = (byte)(wssReceivedBytes[offset + i] ^ masks[i % 4]);
                }

                string receivedFromClient = Encoding.UTF8.GetString(decoded);

                var wssResponse = await RoutingHandler.HandleWss(new HttpRequest()
                {
                    UrlRelative    = firstRequestOfHandShake.UrlRelative,
                    Method         = "wss",
                    CreatedAt      = DateTime.Now,
                    Body           = receivedFromClient,
                    RemoteEndPoint = clientWssAccepted.Client.RemoteEndPoint.ToString()
                });

                WebsocketServerHub.Send(clientWssAccepted, clientStream, wssResponse);
            }
            else
            {
                Console.WriteLine("mask bit not set");
            }
        }
예제 #2
0
        public static void Publish(string urlRelative, IResponse response)
        {
            if (_channel.TryGetValue(urlRelative, out BlockingCollection <KeyValuePair <TcpClient, NetworkStream> > clients) &&
                clients != null)
            {
                List <Task> tasks = new List <Task>();
                foreach (var client in clients)
                {
                    tasks.Add(Task.Run(() =>
                    {
                        if (!client.Key.Client.Connected)
                        {
                            WebsocketServerHub.Remove(urlRelative);
                            return;
                        }
                        WebsocketServerHub.Send(client.Key, client.Value, response);
                    }));
                }

                //want to make sure sent all to client
                //Task.WhenAll(tasks).GetAwaiter().GetResult();
            }
        }