/// <summary>
        /// The Write
        /// </summary>
        /// <param name="client">The client<see cref="WebSocketClient"/></param>
        /// <param name="message">The message<see cref="string"/></param>
        /// <returns>The <see cref="bool"/></returns>
        public bool Write(WebSocketClient client, string message)
        {
            try
            {
                var    nextValue = Encoding.UTF8.GetBytes(message);
                byte[] send      = new byte[2 + nextValue.Length];
                send[0] = 0x80 + 0x1;                                 // last frame, text
                send[1] = BitConverter.GetBytes(nextValue.Length)[0]; // not masked
                for (var i = 0; i < nextValue.Length; i++)
                {
                    send[2 + i] = nextValue[i];
                }

                return(writeDataInStream(client.Stream, send));
            }
            catch (Exception e) { return(false); }
        }
        /// <summary>
        /// The Start
        /// </summary>
        /// <param name="port">The port<see cref="int"/></param>
        /// <returns>The <see cref="Task"/></returns>
        public async Task Start(int port = 8990)
        {
            Port = port;
            if (started)
            {
                Console.WriteLine("WebSocket server already started");
                return;
            }

            started = true;
            TcpListener listener = new TcpListener(IPAddress.Any, port);

            listener.Start();
            Console.WriteLine("WebSocket server started");

            while (true)
            {
                Console.WriteLine("Waiting for new connection..");
                var client = new WebSocketClient(await listener.AcceptTcpClientAsync());

                m_connectedClients.Add(client);

                Console.WriteLine($"New client from {client.RemoteEndPoint}");
                Console.WriteLine($"Actually there are {m_connectedClients.Count} connected");

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                Task.Factory.StartNew(() =>
                {
                    client.Handshake += onClientHandshake;
                    client.Message   += onClientMessage;

                    client.StartListen().ContinueWith((o) =>
                    {
                        m_connectedClients.Remove(client);
                        client.Dispose();
                        Console.WriteLine($"Client removed, now there are {m_connectedClients.Count} connected");
                    });
                });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            }
        }
Example #3
0
        /// <summary>
        /// The sendData
        /// </summary>
        /// <param name="client">The client<see cref="WebSocketClient"/></param>
        internal static void sendData(WebSocketClient client)
        {
            if (m_registeredClient.Contains(client.Id))
            {
#if FULL_LOG
                Console.WriteLine($"Client {client.Id} already registered");
#endif
                return;
            }

            var rng = new Random();
            m_registeredClient.Add(client.Id);
            while (m_registeredClient.Contains(client.Id))
            {
                if (!WebSocketServer.Istance.Write(client, rng.Next(1, 100).ToString()))
                {
                    return;
                }
                Thread.Sleep(1000 / 15);
            }
        }
        /// <summary>
        /// The onClientMessage
        /// </summary>
        /// <param name="sender">The sender<see cref="WebSocketClient"/></param>
        /// <param name="e">The e<see cref="WebSocketDataEventArgs"/></param>
        private void onClientMessage(WebSocketClient sender, WebSocketDataEventArgs e)
        {
            /*
             * Parse message as described in
             * https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_server#collapse-3
             */

            var byte1 = e.Data[0]; // should be 129 for text

            var received = getBytesBit(byte1);
            var opCode   = convertBitArrayToNumber(new[] { received[4], received[5], received[6], received[7] });

#if FULL_LOG
            Console.WriteLine($"{received[0]} - FIN");
            Console.WriteLine($"{received[1]} - RSV1");
            Console.WriteLine($"{received[2]} - RSV2");
            Console.WriteLine($"{received[3]} - RSV3");
            Console.WriteLine($"{opCode} - Opcode");
#endif
            try
            {
                switch (opCode)
                {
                case 0x0:
                    Console.WriteLine($"Received unmanaged `binary` from client {sender.RemoteEndPoint}");
                    break;    // denotes a continuation frame

                case 0x1:     // denotes a text frame
                    Console.WriteLine($"Received `text` from client {sender.RemoteEndPoint}");
                    manageTextReceived(sender, e.Data);
                    break;

                case 0x2: break;     // reserved for further non-control frames

                case 0x3: break;

                case 0x4: break;

                case 0x5: break;

                case 0x6: break;

                case 0x7: break;

                case 0x8:
                    Console.WriteLine($"Received `close connection` from client {sender.RemoteEndPoint}");
                    sender.Dispose();
                    break;    // denotes a connection close

                case 0x9:
                    Console.WriteLine($"Received `ping` from client {sender.RemoteEndPoint}, send `pong`");
                    SendPong(sender);
                    break;    // denotes a ping

                case 0xA:
                    Console.WriteLine($"Received `pong` from client {sender.RemoteEndPoint}, it's alive");
                    break;       // denotes a pong

                case 0xB: break; //reserved for further control frames

                case 0xC: break;

                case 0xD: break;

                case 0xE: break;

                case 0xF: break;

                default:
                    Console.WriteLine($"Received unknown opcode `{opCode}`. Close connection.");
                    sender.Dispose();
                    break;
                }
            }
            catch (Exception)
            {
                sender.Dispose();
            }
        }