コード例 #1
0
 public TClientContext(IWebSocketClientContext client)
 {
     using (EneterTrace.Entering())
     {
         myClient = client;
     }
 }
コード例 #2
0
        public void Query()
        {
            //EneterTrace.DetailLevel = EneterTrace.EDetailLevel.Debug;
            Uri anAddress = new Uri("ws://localhost:8087/MyService/");


            WebSocketListener aService = new WebSocketListener(anAddress);

            // Client will connect with the query.
            Uri             aClientUri = new Uri(anAddress.ToString() + "?UserName=user1&Amount=1");
            WebSocketClient aClient    = new WebSocketClient(aClientUri);

            try
            {
                AutoResetEvent aClientConnectedEvent = new AutoResetEvent(false);

                IWebSocketClientContext aClientContext = null;

                // Start listening.
                aService.StartListening(clientContext =>
                {
                    aClientContext = clientContext;

                    // Indicate the client is connected.
                    aClientConnectedEvent.Set();
                });

                aClient.OpenConnection();

                // Wait until the service accepted and opened the connection.
                Assert.IsTrue(aClientConnectedEvent.WaitOne(3000));
                //aClientConnectedEvent.WaitOne();

                // Check if the query is received.
                Assert.AreEqual("?UserName=user1&Amount=1", aClientContext.Uri.Query);
                Assert.AreEqual(aClientUri, aClientContext.Uri);
            }
            finally
            {
                aClient.CloseConnection();
                aService.StopListening();
            }
        }
コード例 #3
0
        public void CustomHeaderFields()
        {
            Uri anAddress = new Uri("ws://127.0.0.1:8087/MyService/");
            WebSocketListener aService = new WebSocketListener(anAddress);

            // Client will connect with the query.
            WebSocketClient aClient = new WebSocketClient(anAddress);

            try
            {
                AutoResetEvent aClientConnectedEvent = new AutoResetEvent(false);

                IWebSocketClientContext aClientContext = null;

                // Start listening.
                aService.StartListening(clientContext =>
                {
                    aClientContext = clientContext;

                    // Indicate the client is connected.
                    aClientConnectedEvent.Set();
                });

                aClient.HeaderFields["My-Key1"] = "hello1";
                aClient.HeaderFields["My-Key2"] = "hello2";
                aClient.OpenConnection();

                // Wait until the service accepted and opened the connection.
                //Assert.IsTrue(aClientConnectedEvent.WaitOne(3000));
                aClientConnectedEvent.WaitOne();

                // Check if the query is received.
                Assert.AreEqual("hello1", aClientContext.HeaderFields["My-Key1"]);
                Assert.AreEqual("hello2", aClientContext.HeaderFields["My-Key2"]);
            }
            finally
            {
                aClient.CloseConnection();
                aService.StopListening();
            }
        }
コード例 #4
0
        public void Echo()
        {
            Uri anAddress = new Uri("ws://127.0.0.1:8087/");

            WebSocketListener aService = new WebSocketListener(anAddress);
            WebSocketClient   aClient  = new WebSocketClient(anAddress);

            try
            {
                AutoResetEvent aClientOpenedConnectionEvent    = new AutoResetEvent(false);
                AutoResetEvent aResponseReceivedEvent          = new AutoResetEvent(false);
                AutoResetEvent aClientContextReceivedPongEvent = new AutoResetEvent(false);
                AutoResetEvent aClientContextDisconnectedEvent = new AutoResetEvent(false);

                byte[] aReceivedBinMessage  = null;
                string aReceivedTextMessage = "";

                bool aClientContextReceivedPong            = false;
                bool aClientContextReceivedCloseConnection = false;
                bool aClientContextDisconnectedAfterClose  = false;

                IPEndPoint aClientAddress = null;

                IWebSocketClientContext aClientContext = null;

                // Start listening.
                aService.StartListening(clientContext =>
                {
                    aClientContext = clientContext;

                    aClientAddress = aClientContext.ClientEndPoint;

                    clientContext.PongReceived += (x, y) =>
                    {
                        aClientContextReceivedPong = true;
                        aClientContextReceivedPongEvent.Set();
                    };

                    clientContext.ConnectionClosed += (x, y) =>
                    {
                        aClientContextReceivedCloseConnection = true;
                        aClientContextDisconnectedAfterClose  = !clientContext.IsConnected;
                        aClientContextDisconnectedEvent.Set();
                    };

                    WebSocketMessage aWebSocketMessage;
                    while ((aWebSocketMessage = clientContext.ReceiveMessage()) != null)
                    {
                        if (!aWebSocketMessage.IsText)
                        {
                            aReceivedBinMessage = aWebSocketMessage.GetWholeMessage();

                            // echo
                            clientContext.SendMessage(aReceivedBinMessage);
                        }
                        else
                        {
                            aReceivedTextMessage = aWebSocketMessage.GetWholeTextMessage();

                            // echo
                            clientContext.SendMessage(aReceivedTextMessage);
                        }
                    }
                });

                // Client opens connection.
                bool   aClientReceivedPong     = false;
                bool   aClientOpenedConnection = false;
                byte[] aReceivedBinResponse    = null;
                string aReceivedTextResponse   = "";

                aClient.ConnectionOpened += (x, y) =>
                {
                    aClientOpenedConnection = true;
                    aClientOpenedConnectionEvent.Set();
                };
                aClient.PongReceived    += (x, y) => aClientReceivedPong = true;
                aClient.MessageReceived += (x, y) =>
                {
                    if (!y.IsText)
                    {
                        aReceivedBinResponse = y.GetWholeMessage();
                    }
                    else
                    {
                        aReceivedTextResponse = y.GetWholeTextMessage();
                    }

                    aResponseReceivedEvent.Set();
                };

                aClient.OpenConnection();
                aClientOpenedConnectionEvent.WaitOne();

                Assert.IsTrue(aClientOpenedConnection);
                Assert.AreEqual("127.0.0.1", aClientAddress.Address.ToString());
                Assert.AreNotEqual(8087, aClientAddress.Port);

                aClient.SendMessage("He", false);
                aClient.SendMessage("ll", false);
                aClient.SendPing();
                aClient.SendMessage("o", true);

                aResponseReceivedEvent.WaitOne();

                Assert.AreEqual("Hello", aReceivedTextMessage);
                Assert.AreEqual("Hello", aReceivedTextResponse);

                // Client sent ping so it had to receive back the pong.
                Assert.IsTrue(aClientReceivedPong);

                aClientContext.SendPing();

                aClientContextReceivedPongEvent.WaitOne();

                // Service sent ping via the client context - pong had to be received.
                Assert.IsTrue(aClientContextReceivedPong);


                byte[] aBinaryMessage = { 1, 2, 3, 100, 200 };
                aClient.SendMessage(new byte[] { 1, 2, 3 }, false);
                aClient.SendMessage(new byte[] { 100, 200 }, true);

                aResponseReceivedEvent.WaitOne();

                Assert.AreEqual(aBinaryMessage, aReceivedBinMessage);
                Assert.AreEqual(aBinaryMessage, aReceivedBinResponse);

                aClient.CloseConnection();

                aClientContextDisconnectedEvent.WaitOne();

                Assert.IsTrue(aClientContextReceivedCloseConnection);
                Assert.IsTrue(aClientContextDisconnectedAfterClose);
            }
            finally
            {
                aClient.CloseConnection();
                aService.StopListening();
            }
        }
コード例 #5
0
        private void HandleConnection(IWebSocketClientContext client)
        {
            using (EneterTrace.Entering())
            {
                string aClientIp = (client.ClientEndPoint != null) ? client.ClientEndPoint.ToString() : "";

                TClientContext aClientContext = new TClientContext(client);
                string         aClientId      = null;
                try
                {
                    client.SendTimeout    = mySendTimeout;
                    client.ReceiveTimeout = myReceiveTimeout;

                    // If protocol formatter does not use OpenConnection message.
                    if (!myProtocolUsesOpenConnectionMessage)
                    {
                        aClientId = Guid.NewGuid().ToString();
                        using (ThreadLock.Lock(myConnectedClients))
                        {
                            myConnectedClients[aClientId] = aClientContext;
                        }

                        ProtocolMessage anOpenConnectionProtocolMessage = new ProtocolMessage(EProtocolMessageType.OpenConnectionRequest, aClientId, null);
                        MessageContext  aMessageContext = new MessageContext(anOpenConnectionProtocolMessage, aClientIp);
                        NotifyMessageContext(aMessageContext);
                    }

                    while (true)
                    {
                        // Block until a message is received or the connection is closed.
                        WebSocketMessage aWebSocketMessage = client.ReceiveMessage();

                        if (aWebSocketMessage != null && myMessageHandler != null)
                        {
                            ProtocolMessage aProtocolMessage = myProtocolFormatter.DecodeMessage((Stream)aWebSocketMessage.InputStream);

                            // Note: security reasons ignore close connection message in WebSockets.
                            //       So that it is not possible that somebody will just send a close message which will have id of somebody else.
                            //       The connection will be closed when the client closes the socket.
                            if (aProtocolMessage != null && aProtocolMessage.MessageType != EProtocolMessageType.CloseConnectionRequest)
                            {
                                MessageContext aMessageContext = new MessageContext(aProtocolMessage, aClientIp);

                                // If protocol formatter uses open connection message to create the connection.
                                if (aProtocolMessage.MessageType == EProtocolMessageType.OpenConnectionRequest &&
                                    myProtocolUsesOpenConnectionMessage)
                                {
                                    // Note: if client id is already set then it means this client has already open connection.
                                    if (string.IsNullOrEmpty(aClientId))
                                    {
                                        aClientId = !string.IsNullOrEmpty(aProtocolMessage.ResponseReceiverId) ? aProtocolMessage.ResponseReceiverId : Guid.NewGuid().ToString();

                                        using (ThreadLock.Lock(myConnectedClients))
                                        {
                                            if (!myConnectedClients.ContainsKey(aClientId))
                                            {
                                                myConnectedClients[aClientId] = aClientContext;
                                            }
                                            else
                                            {
                                                // Note: if the client id already exists then the connection cannot be open
                                                //       and the connection with this  client will be closed.
                                                EneterTrace.Warning(TracedObject + "could not open connection for client '" + aClientId + "' because the client with same id is already connected.");
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        EneterTrace.Warning(TracedObject + "the client '" + aClientId + "' has already open connection.");
                                    }
                                }

                                // Notify message.
                                // Ensure that nobody will try to use id of somebody else.
                                aMessageContext.ProtocolMessage.ResponseReceiverId = aClientId;
                                NotifyMessageContext(aMessageContext);
                            }
                            else if (aProtocolMessage == null)
                            {
                                // Client disconnected. Or the client shall be disconnected because of incorrect message format.
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                finally
                {
                    // Remove client from connected clients.
                    if (aClientId != null)
                    {
                        using (ThreadLock.Lock(myConnectedClients))
                        {
                            myConnectedClients.Remove(aClientId);
                        }
                    }

                    // If the disconnection does not come from the service
                    // and the client was successfuly connected then notify about the disconnection.
                    if (!aClientContext.IsClosedFromService && aClientId != null)
                    {
                        ProtocolMessage aCloseProtocolMessage = new ProtocolMessage(EProtocolMessageType.CloseConnectionRequest, aClientId, null);
                        MessageContext  aMessageContext       = new MessageContext(aCloseProtocolMessage, aClientIp);

                        // Notify duplex input channel about the disconnection.
                        NotifyMessageContext(aMessageContext);
                    }

                    client.CloseConnection();
                }
            }
        }