public TClientContext(IWebSocketClientContext client) { using (EneterTrace.Entering()) { myClient = client; } }
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(); } }
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(); } }
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(); } }
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(); } } }