/// <summary> /// Reads first Hello message from client /// </summary> private async Task <bool> ProcessFirstMessage(HorseMessage message, IConnectionInfo info, ProtocolHandshakeResult handshakeResult) { if (message.Type != MessageType.Server || message.ContentType != KnownContentTypes.Hello) { return(false); } ConnectionData connectionData = new ConnectionData(); message.Content.Position = 0; await connectionData.ReadFromStream(message.Content); HorseServerSocket socket = await _handler.Connected(_server, info, connectionData); if (socket == null) { info.Close(); return(false); } info.State = ConnectionStates.Pipe; handshakeResult.Socket = socket; _server.HeartbeatManager.Add(socket); socket.SetCleanupAction(s => { _server.HeartbeatManager.Remove(socket); _handler.Disconnected(_server, s); }); return(true); }
/// <summary> /// Handles the connection and reads received HMQ messages /// </summary> public async Task HandleConnection(IConnectionInfo info, ProtocolHandshakeResult handshakeResult) { //if user makes a mistake in ready method, we should not interrupt connection handling try { await _handler.Ready(_server, (HorseServerSocket)handshakeResult.Socket); } catch (Exception e) { if (_server.Logger != null) { _server.Logger.LogException("Unhandled Exception", e); } } HmqReader reader = new HmqReader(); while (info.Client != null && info.Client.Connected) { HorseMessage message = await reader.Read(info.GetStream()); if (message == null) { info.Close(); return; } await ProcessMessage(info, message, (HorseServerSocket)handshakeResult.Socket); } }
/// <summary> /// After protocol handshake is completed, this method is called to handle events for the specified client /// </summary> public async Task HandleConnection(IConnectionInfo info, ProtocolHandshakeResult handshakeResult) { //if user makes a mistake in ready method, we should not interrupt connection handling try { await _handler.Ready(_server, (WsServerSocket)handshakeResult.Socket); } catch (Exception e) { if (_server.Logger != null) { _server.Logger.LogException("Unhandled Exception", e); } } WebSocketReader reader = new WebSocketReader(); Stream stream = info.GetStream(); while (info.Socket != null && info.Socket.IsConnected) { WebSocketMessage message = await reader.Read(stream); if (message == null) { info.Close(); return; } handshakeResult.Socket.KeepAlive(); await ProcessMessage(info, handshakeResult.Socket, message); } }
/// <summary> /// After protocol handshake is completed, this method is called to handle events for the specified client /// </summary> public async Task HandleConnection(IConnectionInfo info, ProtocolHandshakeResult handshakeResult) { //if user makes a mistake in ready method, we should not interrupt connection handling try { await _handler.Ready(_server, handshakeResult.Socket); } catch (Exception e) { if (_server.Logger != null) { _server.Logger.LogException("Unhandled Exception", e); } } HttpReader reader = new HttpReader(Options); HttpWriter writer = new HttpWriter(Options); reader.HandshakeResult = handshakeResult; HandleStatus status; do { HttpMessage message = await reader.Read(info.GetStream()); if (message.Request != null) { message.Request.IpAddress = FindIPAddress(info.Client); } status = await ProcessMessage(info, writer, message, reader.ContentLength); if (status == HandleStatus.ReadAgain) { reader.Reset(); } } while (status == HandleStatus.ReadAgain); if (status == HandleStatus.Close) { info.Close(); } }
/// <summary> /// Switches client's protocol to new protocol (finds by name) /// </summary> public async Task SwitchProtocol(IConnectionInfo info, string newProtocolName, ConnectionData data) { foreach (ITwinoProtocol protocol in Protocols) { if (protocol.Name.Equals(newProtocolName, StringComparison.InvariantCultureIgnoreCase)) { ProtocolHandshakeResult hsresult = await protocol.SwitchTo(info, data); if (!hsresult.Accepted) { info.Close(); return; } ITwinoProtocol previous = info.Protocol; info.Protocol = protocol; info.Socket = hsresult.Socket; if (info.Socket != null) { info.Socket.SetOnConnected(); } if (hsresult.Response != null) { await info.GetStream().WriteAsync(hsresult.Response); } if (info.Socket != null) { info.Socket.SetOnProtocolSwitched(previous, info.Protocol); } await protocol.HandleConnection(info, hsresult); return; } } }
/// <summary> /// Process websocket message /// </summary> private async Task ProcessMessage(IConnectionInfo info, SocketBase socket, WebSocketMessage message) { switch (message.OpCode) { case SocketOpCode.Binary: case SocketOpCode.UTF8: //if user makes a mistake in received method, we should not interrupt connection handling try { await _handler.Received(_server, info, (WsServerSocket)socket, message); } catch (Exception e) { if (_server.Logger != null) { _server.Logger.LogException("Unhandled Exception", e); } } break; //close the connection if terminate requested case SocketOpCode.Terminate: info.Close(); break; //if client sends a ping message, response with pong case SocketOpCode.Ping: await socket.SendAsync(PredefinedMessages.PONG); break; //client sent response pong to ping message case SocketOpCode.Pong: socket.KeepAlive(); break; } }