/// <summary> /// Gets the route table. /// </summary> private IRouteTable BuildRouteTable() { IRouteTable routeTable = new RouteTable(); Assembly entryAssembly = Assembly.GetEntryAssembly(); IEnumerable <Type> connectionRouteAttributeTypes = entryAssembly.GetTypes() .Where(x => x.GetTypeInfo() .GetCustomAttributes() .Any(y => y.GetType() == typeof(ConnectionRouteAttribute))); foreach (Type connectionRouteAttributeType in connectionRouteAttributeTypes) { IEnumerable <ConnectionRouteAttribute> attributes = connectionRouteAttributeType.GetTypeInfo().GetCustomAttributes <ConnectionRouteAttribute>(); if (attributes == null) { continue; } foreach (ConnectionRouteAttribute attribute in attributes) { IWebSocketDataHandler handler = Activator.CreateInstance(connectionRouteAttributeType, _dependencyUtility) as IWebSocketDataHandler; if (handler == null) { continue; } routeTable[attribute.Route] = handler; } } return(routeTable); }
public WebSocketManagerMiddleware(RequestDelegate next, IWebSocketFactory webSocketFactory, IWebSocketDataHandler webSocketDataHandler) { _next = next; _webSocketFactory = webSocketFactory; _webSocketDataHandler = webSocketDataHandler; }
public WebSocketManagerMiddleware(RequestDelegate next, WebSocketConnectionManager webSocketConnectionManager, IWebSocketDataHandler webSocketDataHandler) { _next = next; _webSocketConnectionManager = webSocketConnectionManager; _webSocketDataHandler = webSocketDataHandler; }
/// <summary> /// Handles the handshake. /// </summary> private void HandleHandshake() { const int WEB_SOCKET_VERSION = 13; const string WEB_SOCKET_KEY_HEADER = "Sec-WebSocket-Key"; const string WEB_SOCKET_VERSION_HEADER = "Sec-WebSocket-Version"; HttpMetadata = new HttpMetadata(_frameReader.Stream, _dependencyUtility); if (!HttpMetadata.IsValid) { return; } if (string.IsNullOrEmpty(HttpMetadata.Route) || HttpMetadata.Headers.Count == 0) { KillConnection("Failed to read from stream"); return; } if (!HttpMetadata.Headers.ContainsKey(WEB_SOCKET_KEY_HEADER) || !HttpMetadata.Headers.ContainsKey(WEB_SOCKET_VERSION_HEADER)) { KillConnection("Failed to retrieve websocket headers"); return; } int secWebSocketVersion = Convert.ToInt32(HttpMetadata.Headers[WEB_SOCKET_VERSION_HEADER]); if (secWebSocketVersion < WEB_SOCKET_VERSION) { KillConnection($"WebSocket Version {secWebSocketVersion} not supported. Must be {WEB_SOCKET_VERSION} or higher"); return; } string secWebSocketKey = HttpMetadata.Headers[WEB_SOCKET_KEY_HEADER]; string secWebSocketAccept = ComputeSocketAcceptString(secWebSocketKey); string response = ComputeResponseString(secWebSocketAccept); byte[] responseBytes = Encoding.UTF8.GetBytes(response); _frameReader.Stream.Write(responseBytes, 0, responseBytes.Length); IsValid = true; IWebSocketDataHandler handler = _routeTable[HttpMetadata.Route]; handler?.OnOpen(this, new ConnectionOpenedEventArgs(HttpMetadata.QueryStrings)); }
/// <summary> /// Receives this instance. /// </summary> /// <exception cref="WebSocketClosedException"></exception> private void Receive() { HandleStream(); if (_isDisposing) { return; } if (IsAlive) { HandleHandshake(); } if (!IsValid) { return; } IWebSocketDataHandler handler = _routeTable[HttpMetadata.Route]; if (handler == null) { KillConnection("Invalid route"); return; } while (IsAlive) { HandleFrame(handler); Thread.Sleep(20); } Dispose(); }
/// <summary> /// Handles the frame. /// </summary> /// <param name="handler">The handler.</param> private void HandleFrame(IWebSocketDataHandler handler) { IWebSocketFrame frame = _frameReader.Read(_client); if (frame == null || !frame.IsValid) { return; } if (frame.OpCode == WebSocketOpCode.ContinuationFrame) { switch (_multiFrameOpCode) { case WebSocketOpCode.TextFrame: string message = Encoding.UTF8.GetString(frame.DecodedPayload, 0, frame.DecodedPayload.Length); handler.OnTextPart(this, new TextMultiFrameEventArgs(message, frame.IsEntirePayload)); return; case WebSocketOpCode.BinaryFrame: handler.OnBinaryPart(this, new BinaryMultiFrameEventArgs(frame.DecodedPayload, frame.IsEntirePayload)); return; } } else { switch (frame.OpCode) { case WebSocketOpCode.ConnectionClose: handler.OnClose(this, GetConnectionCloseEventArgsFromPayload(frame.DecodedPayload)); KillConnection(string.Empty); return; case WebSocketOpCode.Ping: handler.OnPing(this, new PingEventArgs(frame.DecodedPayload)); return; case WebSocketOpCode.Pong: handler.OnPong(this, new PingEventArgs(frame.DecodedPayload)); return; case WebSocketOpCode.TextFrame: string message = Encoding.UTF8.GetString(frame.DecodedPayload, 0, frame.DecodedPayload.Length); if (frame.IsEntirePayload) { handler.OnText(this, new TextFrameEventArgs(message)); } else { _multiFrameOpCode = frame.OpCode; handler.OnTextPart(this, new TextMultiFrameEventArgs(message, frame.IsEntirePayload)); } return; case WebSocketOpCode.BinaryFrame: if (frame.IsEntirePayload) { handler.OnBinary(this, new BinaryFrameEventArgs(frame.DecodedPayload)); } else { _multiFrameOpCode = frame.OpCode; handler.OnBinaryPart(this, new BinaryMultiFrameEventArgs(frame.DecodedPayload, frame.IsEntirePayload)); } return; } } }