예제 #1
0
        /// <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);
        }
예제 #2
0
 public WebSocketManagerMiddleware(RequestDelegate next,
                                   IWebSocketFactory webSocketFactory,
                                   IWebSocketDataHandler webSocketDataHandler)
 {
     _next                 = next;
     _webSocketFactory     = webSocketFactory;
     _webSocketDataHandler = webSocketDataHandler;
 }
예제 #3
0
 public WebSocketManagerMiddleware(RequestDelegate next,
                                   WebSocketConnectionManager webSocketConnectionManager,
                                   IWebSocketDataHandler webSocketDataHandler)
 {
     _next = next;
     _webSocketConnectionManager = webSocketConnectionManager;
     _webSocketDataHandler       = webSocketDataHandler;
 }
예제 #4
0
        /// <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));
        }
예제 #5
0
        /// <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();
        }
예제 #6
0
        /// <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;
                }
            }
        }