private static async void OnWebsocketEvent(object sender, WebSocketEventArg args)
 {
     if (args.data != null && args.isText)
     {
         string received = Encoding.UTF8.GetString(args.data);
         await _WebsocketServer.SendTextMessageAsync("Client: " + args.clientId + " on url: " + args.clientBaseUrl + ", says: " + received);
     }
     else
     {
         if (args.isOpen)
         {
             Console.WriteLine("Client: " + args.clientId + " connected!");
             await _WebsocketServer.SendTextMessageAsync("Client: " + args.clientId + " on url: " + args.clientBaseUrl + ", says: " + "joined!");
         }
     }
     if (args.isClosed)
     {
         if (args.data != null)
         {
             string received = Encoding.UTF8.GetString(args.data);
             Console.WriteLine("Client: " + args.clientId + " disconnected with message:");
             Console.WriteLine(received);
         }
         else
         {
             string received = Encoding.UTF8.GetString(args.data);
             Console.WriteLine("Client: " + args.clientId + " disconnected.");
         }
     }
 }
Example #2
0
        /// <summary>
        /// WebSocket Server event handler, fires the event.
        /// </summary>
        /// <param name="arg">Arguments containing event arguments.</param>
        public void OnWebsocketEvent(object sender, WebSocketEventArg arg)
        {
            if (arg.isClosed)
            {
                WebSocketClientInfo key = null;
                bool found = false;

                foreach (var connection in _ListWithConnections)
                {
                    if (connection.Key.clientId == arg.clientId)
                    {
                        key   = connection.Key;
                        found = true;
                        break;
                    }
                }
                if (found)
                {
                    _ListWithConnections.Remove(key);
                }
            }


            WebsocketEvent?.Invoke(this, arg);
        }
        /// <summary>
        /// Starts a connection given the settings set by caller.
        /// </summary>
        /// <param name="client">TcpClient socket handler.</param>
        /// <param name="stream">NetworkStream stream handler.</param>
        /// <param name="clientId">Id of client.</param>
        /// <param name="baseUrl">URL path used by client.</param>
        public async void StartConnection(TcpClient client, string clientId, string baseUrl)
        {
            WebSocketClientInfo info = new WebSocketClientInfo()
            {
                client        = client,
                clientId      = clientId,
                clientBaseUrl = baseUrl
            };

            WebSocketServer newServer = new WebSocketServer(info, _BufferSize);

            newServer.WebSocketServerEvent += OnWebsocketEvent;
            _ListWithConnections.Add(info, newServer);
            try
            {
                await newServer.StartServerAsync();
            }
            catch (Exception)
            {
                WebSocketEventArg args = new WebSocketEventArg()
                {
                    clientId      = clientId,
                    clientBaseUrl = baseUrl,
                    errorMessage  = "Client disconnected forcefully",
                    isClosed      = true
                };
                OnWebsocketEvent(this, args);
            }
        }
        private async void OnWebSocketServerEvent(object sender, WebSocketEventArg args)
        {
            DebugHandler.TraceMessage("OnWebSocketServerEvent Called", DebugSource.TASK, DebugType.ENTRY_EXIT);

            try
            {
                if (args.isOpen)
                {
                    if (!ClientIds.Contains(args.clientId))
                    {
                        DebugHandler.TraceMessage("Client with id " + args.clientId + " from " + args.clientBaseUrl + " connected!", DebugSource.TASK, DebugType.INFO);

                        ClientIds.Add(args.clientId);
                        await SendMessage(new JsonWelcome()
                        {
                            local = LittleWeebSettings.Local
                        }.ToJson());
                    }
                }

                if (args.isClosed)
                {
                    if (ClientIds.Contains(args.clientId))
                    {
                        DebugHandler.TraceMessage("Client with id " + args.clientId + " from " + args.clientBaseUrl + " disconnected!", DebugSource.TASK, DebugType.INFO);
                        ClientIds.Remove(args.clientId);
                    }
                }

                if (args.data != null && args.isText)
                {
                    string received = Encoding.ASCII.GetString(args.data);


                    DebugHandler.TraceMessage(received, DebugSource.TASK, DebugType.INFO);

                    OnWebSocketEvent?.Invoke(this, new WebSocketEventArgs()
                    {
                        Message = received
                    });

                    await SendMessage(new JsonReceivedResponse()
                    {
                        received = received
                    }.ToJson());
                }

                if (args.isPing)
                {
                    DebugHandler.TraceMessage("IsPing: " + args.isPing.ToString(), DebugSource.TASK, DebugType.INFO);
                    await Server.SendPongMessageAsync();
                }

                if (args.isPong)
                {
                    DebugHandler.TraceMessage("IsPong: " + args.isPing.ToString(), DebugSource.TASK, DebugType.INFO);
                    await Server.SendPingMessageAsync();
                }
            }
            catch (Exception e)
            {
                DebugHandler.TraceMessage(e.ToString(), DebugSource.TASK, DebugType.WARNING);
            }
        }
Example #5
0
        /// <summary>
        /// Starts the WebSocket server / connection with the client synchronous.
        /// </summary>
        /// <returns></returns>
        public void StartServer()
        {
            NetworkStream stream = _ClientInfo.client.GetStream();

            byte[] buffer = new byte[_BufferSize];

            List <byte> data = new List <byte>();

            bool continuationFrame = false;

            WebSocketEventArg messageArg = new WebSocketEventArg();

            bool isConnected = false;

            while (_ClientInfo.client.Connected && stream.CanRead)
            {
                messageArg = new WebSocketEventArg()
                {
                    clientBaseUrl = _ClientInfo.clientBaseUrl,
                    clientId      = _ClientInfo.clientId
                };

                if (!isConnected)
                {
                    Thread.Sleep(500);
                    messageArg.clientId = _ClientInfo.clientId;
                    messageArg.isOpen   = true;
                    isConnected         = true;
                    WebSocketServerEvent?.Invoke(this, messageArg);
                }

                int bytesRead = stream.Read(buffer, 0, buffer.Length);
                stream.Flush();
                int    opCode               = buffer[0] & 0x0F;
                bool   finalMessage         = ((buffer[0] & 0x80) == 0x80);
                bool   maskKey              = ((buffer[1] & 0x80) == 0x80);
                UInt64 payloadLength        = 0;
                int    initialPayloadLength = buffer[1] & 0x7F;


                switch (opCode)
                {
                case 0x00:
                    continuationFrame = true;
                    break;

                case 0x01:
                    continuationFrame = false;
                    messageArg.isText = true;
                    break;

                case 0x02:
                    continuationFrame   = false;
                    messageArg.isBinary = true;
                    break;

                case 0x08:
                    continuationFrame   = false;
                    messageArg.isClosed = true;
                    break;

                case 0x09:
                    continuationFrame = false;
                    messageArg.isPing = true;
                    break;

                case 0x0A:
                    continuationFrame = false;
                    messageArg.isPong = true;
                    break;

                default:
                    stream.Close();
                    _ClientInfo.client.Close();
                    break;
                }


                byte[] payloadLengthBytes;
                byte[] maskKeyBytes = new byte[4];

                switch (initialPayloadLength)
                {
                case 126:
                    payloadLengthBytes = new byte[2];
                    Array.Copy(buffer, 2, payloadLengthBytes, 0, payloadLengthBytes.Length);
                    payloadLength = BitConverter.ToUInt16(payloadLengthBytes.Reverse <byte>().ToArray(), 0);

                    messageArg.messageLength = payloadLength;
                    if (maskKey)
                    {
                        Array.Copy(buffer, 4, maskKeyBytes, 0, maskKeyBytes.Length);
                        byte[] tempData = new byte[payloadLength];
                        Array.Copy(buffer, 8, tempData, 0, tempData.Length);

                        for (int i = 0; i < tempData.Length; i++)
                        {
                            tempData[i] = (byte)(maskKeyBytes[i % 4] ^ tempData[i]);
                        }

                        data.AddRange(tempData);
                    }
                    else
                    {
                        byte[] tempData = new byte[payloadLength];
                        Array.Copy(buffer, 4, tempData, 0, tempData.Length);
                        data.AddRange(tempData);
                    }

                    break;

                case 127:
                    payloadLengthBytes = new byte[8];
                    Array.Copy(buffer, 2, payloadLengthBytes, 0, payloadLengthBytes.Length);
                    payloadLength            = BitConverter.ToUInt64(payloadLengthBytes.Reverse <byte>().ToArray(), 0);
                    messageArg.messageLength = payloadLength;

                    if (maskKey)
                    {
                        Array.Copy(buffer, 10, maskKeyBytes, 0, maskKeyBytes.Length);
                        byte[] tempData = new byte[payloadLength];

                        Array.Copy(buffer, 14, tempData, 0, tempData.Length);
                        for (int i = 0; i < tempData.Length; i++)
                        {
                            tempData[i] = (byte)(maskKeyBytes[i % 4] ^ tempData[i]);
                        }
                        data.AddRange(tempData);
                    }
                    else
                    {
                        byte[] tempData = new byte[payloadLength];

                        Array.Copy(buffer, 10, tempData, 0, tempData.Length);
                        data.AddRange(tempData);
                    }
                    break;

                default:
                    payloadLength            = (uint)initialPayloadLength;
                    messageArg.messageLength = payloadLength;

                    if (maskKey)
                    {
                        Array.Copy(buffer, 2, maskKeyBytes, 0, maskKeyBytes.Length);
                        byte[] tempData = new byte[payloadLength];
                        Array.Copy(buffer, 6, tempData, 0, tempData.Length);
                        for (int i = 0; i < tempData.Length; i++)
                        {
                            tempData[i] = (byte)(maskKeyBytes[i % 4] ^ tempData[i]);
                        }
                        data.AddRange(tempData);
                    }
                    else
                    {
                        byte[] tempData = new byte[(bytesRead - 2)];
                        Array.Copy(buffer, 2, tempData, 0, tempData.Length);
                        data.AddRange(tempData);
                    }
                    break;
                }


                if (!continuationFrame && finalMessage)
                {
                    messageArg.data = data.ToArray();
                    WebSocketServerEvent?.Invoke(this, messageArg);

                    data.Clear();
                }
            }

            messageArg.isOpen = false;
            WebSocketServerEvent?.Invoke(this, messageArg);
        }