예제 #1
0
        private void ProcessWebSocketRequest(HttpListenerContext ctx)
        {
            try
            {
                var endpoint    = ctx.Request.RemoteEndPoint.ToString();
                var url         = ctx.Request.RawUrl;
                var queryString = new NameValueCollection(ctx.Request.QueryString ?? new NameValueCollection());

                var connectingArgs = new WebSocketConnectingEventArgs
                {
                    Url         = url,
                    QueryString = queryString,
                    Endpoint    = endpoint
                };

                if (WebSocketConnecting != null)
                {
                    WebSocketConnecting(connectingArgs);
                }

                if (connectingArgs.AllowConnection)
                {
                    _logger.Debug("Web socket connection allowed");

                    var webSocketContext = ctx.AcceptWebSocket(null);

                    if (WebSocketConnected != null)
                    {
                        WebSocketConnected(new WebSocketConnectEventArgs
                        {
                            Url         = url,
                            QueryString = queryString,
                            WebSocket   = new SharpWebSocket(webSocketContext.WebSocket, _logger),
                            Endpoint    = endpoint
                        });
                    }
                }
                else
                {
                    _logger.Warn("Web socket connection not allowed");
                    ctx.Response.StatusCode = 401;
                    ctx.Response.Close();
                }
            }
            catch (Exception ex)
            {
                _logger.ErrorException("AcceptWebSocketAsync error", ex);
                ctx.Response.StatusCode = 500;
                ctx.Response.Close();
            }
        }
예제 #2
0
        private bool upgradeToWebSocket(HttpListenerContext context)
        {
            var res       = context.Response;
            var wsContext = context.AcceptWebSocket();
            var path      = wsContext.Path.UrlDecode();

            IServiceHost svcHost;

            if (!_svcHosts.TryGetServiceHost(path, out svcHost))
            {
                res.StatusCode = (int)HttpStatusCode.NotImplemented;
                return(false);
            }

            svcHost.BindWebSocket(wsContext);
            return(true);
        }
        private bool processWebSocketRequest(HttpListenerContext context)
        {
            var wsContext = context.AcceptWebSocket();

            var path = wsContext.Path;
            WebSocketServiceHost host;

            if (path == null || !_serviceHosts.TryGetServiceHostInternally(path, out host))
            {
                context.Response.StatusCode = (int)HttpStatusCode.NotImplemented;
                return(false);
            }

            wsContext.WebSocket.Log = _logger;
            host.StartSession(wsContext);

            return(true);
        }
예제 #4
0
        private bool processWebSocketRequest(HttpListenerContext context)
        {
            var wsContext = context.AcceptWebSocket();
            var path      = wsContext.Path.UrlDecode();

            IServiceHost svcHost;

            if (!_svcHosts.TryGetServiceHost(path, out svcHost))
            {
                context.Response.StatusCode = (int)HttpStatusCode.NotImplemented;
                return(false);
            }

            wsContext.WebSocket.Log = _logger;
            svcHost.BindWebSocket(wsContext);

            return(true);
        }
예제 #5
0
        private void ProcessWebSocketRequest(HttpListenerContext ctx)
        {
            try
            {
                var webSocketContext = ctx.AcceptWebSocket(null);

                if (WebSocketHandler != null)
                {
                    WebSocketHandler(new WebSocketConnectEventArgs
                    {
                        WebSocket = new SharpWebSocket(webSocketContext.WebSocket, _logger),
                        Endpoint  = ctx.Request.RemoteEndPoint.ToString()
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.ErrorException("AcceptWebSocketAsync error", ex);
                ctx.Response.StatusCode = 500;
                ctx.Response.Close();
            }
        }
예제 #6
0
        /// <summary>
        /// Accepts the WebSocket connection.
        /// This is a blocking call so it must be called within an independent thread.
        /// </summary>
        /// <param name="server">The server.</param>
        /// <param name="context">The context.</param>
        public void AcceptWebSocket(WebServer server, HttpListenerContext context)
        {
            // first, accept the websocket
            WebServer = server;
            server.Log.DebugFormat("{0} - Accepting WebSocket . . .", ServerName);
#if NET46
            const int receiveBufferSize = 2048;
#endif

            var webSocketContext =
#if NET46
                context.AcceptWebSocketAsync(subProtocol: null, receiveBufferSize: receiveBufferSize,
                                             keepAliveInterval: TimeSpan.FromSeconds(30))
                .GetAwaiter()
                .GetResult();
#else
                context.AcceptWebSocket(null, WebServer.Log);
#endif

            // remove the disconnected clients
            CollectDisconnected();
            lock (_syncRoot)
            {
                // add the newly-connected client
                _mWebSockets.Add(webSocketContext);
            }

            server.Log.DebugFormat(
                $"{ServerName} - WebSocket Accepted - There are {WebSockets.Count} sockets connected.");
            // call the abstract member
            OnClientConnected(webSocketContext);

            try
            {
#if NET46
// define a receive buffer
                var receiveBuffer = new byte[receiveBufferSize];
                // define a dynamic buffer that holds multi-part receptions
                var receivedMessage = new List <byte>(receiveBuffer.Length * 2);

                // poll the WebSockets connections for reception
                while (webSocketContext.WebSocket.State == WebSocketState.Open)
                {
                    // retrieve the result (blocking)
                    var receiveResult =
                        webSocketContext.WebSocket.ReceiveAsync(new ArraySegment <byte>(receiveBuffer),
                                                                CancellationToken.None).GetAwaiter().GetResult();
                    if (receiveResult.MessageType == WebSocketMessageType.Close)
                    {
                        // close the connection if requested by the client
                        webSocketContext.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty,
                                                              CancellationToken.None).GetAwaiter().GetResult();
                        return;
                    }

                    var frameBytes = new byte[receiveResult.Count];
                    Array.Copy(receiveBuffer, frameBytes, frameBytes.Length);
                    this.OnFrameReceived(webSocketContext, frameBytes, receiveResult);

                    // add the response to the multi-part response
                    receivedMessage.AddRange(frameBytes);

                    if (receivedMessage.Count > _maximumMessageSize && _maximumMessageSize > 0)
                    {
                        // close the connection if message exceeds max length
                        webSocketContext.WebSocket.CloseAsync(
                            WebSocketCloseStatus.MessageTooBig,
                            $"Message too big. Maximum is {_maximumMessageSize} bytes.",
                            CancellationToken.None).GetAwaiter().GetResult();

                        // exit the loop; we're done
                        return;
                    }

                    // if we're at the end of the message, process the message
                    if (receiveResult.EndOfMessage)
                    {
                        this.OnMessageReceived(webSocketContext, receivedMessage.ToArray(), receiveResult);
                        receivedMessage.Clear();
                    }
                }
#else
                // TODO: Pending OnFrameReceived
                webSocketContext.WebSocket.OnMessage += (s, e) =>
                {
                    var isText = e.IsText ? WebSocketMessageType.Text : WebSocketMessageType.Binary;

                    OnMessageReceived(webSocketContext,
                                      e.RawData,
                                      new WebSocketReceiveResult(e.RawData.Length, isText, e.Opcode == Opcode.Close));
                };

                while (webSocketContext.WebSocket.IsConnected)
                {
                    Task.Delay(100).Wait();
                }
#endif
            }
            catch (Exception ex)
            {
                server.Log.ErrorFormat("{0} - Error: {1}", ServerName, ex);
            }
            finally
            {
                // once the loop is completed or connection aborted, remove the WebSocket
                RemoveWebSocket(webSocketContext);
            }
        }