コード例 #1
0
        private async Task processSocketAsync(
            WebSocket socket)
        {
            using (socket)
            {
                // Begin sending and receiving.
                var receiving = startReceiving(socket);
                var sending   = startSending(socket);

                // Wait for send or receive to complete
                var trigger = await Task.WhenAny(receiving, sending)
                              .ConfigureAwait(false);

                if (trigger == receiving)
                {
                    // We're waiting for the application to finish and there are 2 things it could be doing
                    // 1. Waiting for application data
                    // 2. Waiting for a websocket send to complete

                    // Cancel the application so that ReadAsync yields
                    _application.Input.CancelPendingRead();

                    using var delayCts = new CancellationTokenSource();

                    var resultTask = await Task.WhenAny(sending,
                                                        Task.Delay(Timeout.InfiniteTimeSpan, delayCts.Token))
                                     .ConfigureAwait(false);

                    if (resultTask != sending)
                    {
                        _aborted = true;

                        // Abort the websocket if we're stuck in a pending send to the client
                        socket.Abort();
                    }
                    else
                    {
                        // Cancel the timeout
                        delayCts.Cancel();
                    }
                }
                else
                {
                    // We're waiting on the websocket to close and there are 2 things it could be doing
                    // 1. Waiting for websocket data
                    // 2. Waiting on a flush to complete (back pressure being applied)
                    _aborted = true;

                    // Abort the websocket if we're stuck in a pending receive from the client
                    socket.Abort();

                    // Cancel any pending flush so that we can quit
                    _application.Output.CancelPendingFlush();
                }
            }
        }
コード例 #2
0
ファイル: Interact.cs プロジェクト: bopohaa/DistributedCache
 public void Dispose()
 {
     if (!_socket.CloseStatus.HasValue)
     {
         _socket.Abort();
     }
 }
コード例 #3
0
        internal async Task CleanupAsync()
        {
            switch (_webSocket.State)
            {
            case WebSocketState.Closed:     // Closed gracefully, no action needed.
            case WebSocketState.Aborted:    // Closed abortively, no action needed.
                break;

            case WebSocketState.CloseReceived:
                // Attempt a graceful closure on behalf of the application, but don't wait too long.
                using (var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken))
                {
                    timeoutCts.CancelAfter(TimeSpan.FromSeconds(15));
                    // Echo what the client said, if anything.
                    await _webSocket.CloseAsync(_webSocket.CloseStatus ?? WebSocketCloseStatus.NormalClosure,
                                                _webSocket.CloseStatusDescription ?? string.Empty, timeoutCts.Token);
                }
                break;

            case WebSocketState.Open:
            case WebSocketState.CloseSent:     // No close received, abort so we don't have to drain the pipe.
                _webSocket.Abort();
                break;

            default:
                throw new ArgumentOutOfRangeException("state", _webSocket.State, string.Empty);
            }
        }
コード例 #4
0
        private async Task Receive(WebSocket socket, Action <WebSocketReceiveResult, HardwareId, string> handleMessage)
        {
            while (socket.State == WebSocketState.Open)
            {
                ArraySegment <byte> buffer    = new ArraySegment <byte>(new byte[1024 * 4]);
                string message                = null;
                WebSocketReceiveResult result = null;
                try {
                    using (var ms = new MemoryStream()) {
                        do
                        {
                            result = await socket.ReceiveAsync(buffer, CancellationToken.None).ConfigureAwait(false);

                            ms.Write(buffer.Array, buffer.Offset, result.Count);
                        } while (!result.EndOfMessage);

                        ms.Seek(0, SeekOrigin.Begin);

                        using (var reader = new StreamReader(ms, Encoding.UTF8)) {
                            message = await reader.ReadToEndAsync().ConfigureAwait(false);
                        }
                    }

                    var fields     = message.Split(',');
                    var hardwareId = new HardwareId(fields[0]);

                    handleMessage(result, hardwareId, fields[1]);
                } catch (WebSocketException e) {
                    if (e.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely)
                    {
                        socket.Abort();
                    }
                }
            }
        }
コード例 #5
0
        private async Task <Message> WaitForAuthenticationMessage(WebSocket socket)
        {
            Message message = null;

            CancellationTokenSource ct = new CancellationTokenSource(SOCKET_TIMEOUT);

            SegmentInputBuffer = new ArraySegment <byte>(new byte[MAX_BUFFER_LEN]);

            try
            {
                var result = await socket.ReceiveAsync(SegmentInputBuffer, ct.Token);

                if (result.MessageType == WebSocketMessageType.Text)
                {
                    byte[] buffer = new byte[result.Count];
                    Array.Copy(SegmentInputBuffer.Array, buffer, buffer.Length);

                    message = JsonConvert.DeserializeObject <Message>(Encoding.UTF8.GetString(buffer));
                    if (message.Type != MessageType.AUTHENTICATE)
                    {
                        throw new Exception("Message received was not an authentication message.");
                    }
                }
            }
            catch (Exception ex)
            {
                socket.CloseOutputAsync(WebSocketCloseStatus.InternalServerError, $"Authentication Step Error : [{ex.Message}]", CancellationToken.None).GetAwaiter().GetResult();
                socket.Abort();

                throw ex;
            }

            return(message);
        }
コード例 #6
0
        /// <summary>
        /// 关闭连接
        /// </summary>
        /// <returns></returns>
        public void ClosedConnect()
        {
            try
            {
                //清除定时器
                ClearTimer();

                //取消订阅
                RedisHelper.Publish(_socketid, "stop");

                //移除在线状态
                CacheManager.RedisChat.Del(_imuserid.AddCachePrefix("Online"));

                //发送离线通知
                PublishMessage(NewsTypeHelper.ToOffline(_imuserid, _sourcetype));

                //TODO:webSocket 移除处理待优化
                if (_webSocket != null)
                {
                    _webSocket.CloseAsync(WebSocketCloseStatus.Empty, "", _cancellationToken);
                    _webSocket.Abort();
                    _webSocket = null;
                }
            }
            catch (Exception ex)
            {
                LogManager.DefaultLogger.ErrorFormat($"关闭连接异常:error:{ex.Message}");
                _redisClient.Dispose();
            }
        }
コード例 #7
0
        private async Task ValidateConnection(WebSocket socket)
        {
            while (socket.State == WebSocketState.Open)
            {
                CancellationTokenSource ct = new CancellationTokenSource();
                ct.CancelAfter(SOCKET_TIMEOUT);

                Message message = new Message();
                message.Id      = 0;
                message.Channel = "";
                message.Data    = "PING";
                message.Type    = MessageType.PING_PONG;

                await _hub.OnPing(message);

                ArraySegment <byte> segBuffer = new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)));

                await socket.SendAsync(segBuffer, WebSocketMessageType.Text, true, ct.Token);

                if (DateTime.Now.Subtract(lastPong).Milliseconds > SOCKET_TIMEOUT)
                {
                    await socket.CloseOutputAsync(WebSocketCloseStatus.Empty, "Client Unreachable", CancellationToken.None);

                    socket.Abort();
                }

                await Task.Delay(PING_INTERVAL);
            }
        }
コード例 #8
0
        /// <summary>
        /// Run the processing loop for this session.  Intended to be run in a separate thread off of the main WebSocket
        /// server thread.
        /// </summary>
        public async Task Run()
        {
            ArraySegment <byte> buffer = WebSocket.CreateServerBuffer(WEBSOCKET_BUFFER_SIZE);

            while (socket.State != WebSocketState.Closed && socket.State != WebSocketState.Aborted &&
                   !cancelToken.IsCancellationRequested)
            {
                WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, cancelToken);

                // If the token is cancelled during result fetch, then the socket will be unusable
                if (!cancelToken.IsCancellationRequested)
                {
                    if (socket.State == WebSocketState.CloseReceived &&
                        result.MessageType == WebSocketMessageType.Close)
                    {
                        // If the client is closing the session, acknowledge
                        await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Acknowledge session closure",
                                                      CancellationToken.None);
                    }
                    else if (socket.State == WebSocketState.Open)
                    {
                        // Handle client message as a string
                        HandleMessage(Encoding.UTF8.GetString(buffer.Array, 0, result.Count));
                    }
                }
            }

            // Ensure that the socket is not still connected
            if (socket.State != WebSocketState.Closed)
            {
                socket.Abort();
            }
            socket.Dispose();
            OnSocketClosed();
        }
コード例 #9
0
ファイル: WebSocketServer.cs プロジェクト: 3404026/JBBProject
        public async void ProcessClient(WebSocket websocket)
        {
            try
            {
                var data   = new byte[1500];
                var buffer = new ArraySegment <byte>(data);

                while (true)
                {
                    var result = await websocket.ReceiveAsync(buffer, CancellationToken.None);

                    if (result.CloseStatus != null)
                    {
                        Console.WriteLine("socket closed");
                        websocket.Abort();
                        return;
                    }

                    Console.WriteLine(">>> " + Encoding.UTF8.GetString(data, 0, result.Count));
                    await websocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message.ToString());
            }
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: Dylan-Jang/TestWebSocket
        public async Task Connect()
        {
            try
            {
                var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
                await WebSocket.ConnectAsync(Uri, cts.Token);

                Logger.Info(new
                {
                    Event = "connect_to_server",
                    Uri   = Uri,
                });

                WebSocket.Abort();

                Logger.Info(new
                {
                    Event = "connect_closed_successfully",
                    Uri   = Uri,
                });
            }
            catch (Exception e)
            {
                Logger.Error(new
                {
                    Event     = "connect_exception",
                    Uri       = Uri,
                    Exception = e,
                });
            }
        }
コード例 #11
0
        private async Task MessageInputHandler(WebSocket socket)
        {
            while (socket.State == WebSocketState.Open)
            {
                try
                {
                    CancellationTokenSource ct = new CancellationTokenSource();
                    ct.CancelAfter(SOCKET_TIMEOUT);

                    SegmentInputBuffer = new ArraySegment <byte>(new byte[MAX_BUFFER_LEN]);

                    WebSocketReceiveResult result = await socket.ReceiveAsync(SegmentInputBuffer, ct.Token);

                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        byte[] buffer = new byte[result.Count];
                        Array.Copy(SegmentInputBuffer.Array, buffer, buffer.Length);

                        Message message = JsonConvert.DeserializeObject <Message>(Encoding.UTF8.GetString(buffer));
                        //Send message to the correct handler
                        switch (message.Type)
                        {
                        case MessageType.PING_PONG:
                            await _hub.OnPong(message);

                            HandlePong(socket);
                            break;

                        case MessageType.MESSAGE:
                            await _hub.OnIncomingMessage(message);
                            await HandleIncomingMessage(socket, message);

                            break;

                        case MessageType.SUBSCRIBE:
                            await _hub.OnChannelSubscribed(message);
                            await SubscribeToChannel(socket, message);

                            break;

                        case MessageType.UNSUBSCRIBE:
                            await _hub.OnChannelUnsubscribed(message);
                            await UnsubscribeFromChannel(socket, message);

                            break;

                        default:
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    socket.CloseOutputAsync(WebSocketCloseStatus.InternalServerError, ex.Message, CancellationToken.None).GetAwaiter().GetResult();
                    socket.Abort();
                    throw ex;
                }
            }
        }
コード例 #12
0
ファイル: Connection.cs プロジェクト: yahyaguzide/daud
 private void Close()
 {
     try
     {
         Socket.Abort();
     }
     catch (Exception) { }
 }
コード例 #13
0
        public void AbortConnection(Guid connectionid)
        {
            WebSocket ws = null;

            if (!_clients.TryGetValue(connectionid, out ws))
            {
                return;
            }

            ws.Abort();
        }
コード例 #14
0
 public override void Abort()
 {
     if (state == disposed)
     {
         return;
     }
     if (innerWebSocket != null)
     {
         innerWebSocket.Abort();
     }
     Dispose();
 }
コード例 #15
0
ファイル: Connection.cs プロジェクト: xtremi/neo
        private void WsReceive()
        {
            byte[] buffer = new byte[512];
            ws.ReceiveAsync(buffer, CancellationToken.None).PipeTo(Self,
                                                                   success: p =>
            {
                switch (p.MessageType)
                {
                case WebSocketMessageType.Binary:
                    return(new Tcp.Received(ByteString.FromBytes(buffer, 0, p.Count)));

                case WebSocketMessageType.Close:
                    return(Tcp.PeerClosed.Instance);

                default:
                    ws.Abort();
                    return(Tcp.Aborted.Instance);
                }
            },
                                                                   failure: ex => new Tcp.ErrorClosed(ex.Message));
        }
コード例 #16
0
 /// <inheritdoc/>
 public override void Disconnect()
 {
     try
     {
         _webSocket.Abort();
         _clientDisconnectedHandler(this);
     }
     catch (Exception ex)
     {
         Console.WriteLine($"Error: {ex.Message}.");
     }
 }
コード例 #17
0
 private void OnWsConnected(WebSocket ws, IPEndPoint remote, IPEndPoint local)
 {
     ConnectedAddresses.TryGetValue(remote.Address, out int count);
     if (count >= MaxConnectionsPerAddress)
     {
         ws.Abort();
     }
     else
     {
         ConnectedAddresses[remote.Address] = count + 1;
         Context.ActorOf(ProtocolProps(ws, remote, local), $"connection_{Guid.NewGuid()}");
     }
 }
コード例 #18
0
        public async Task Listen()
        {
            byte[] buffer = new byte[1024];
            WebSocketReceiveResult result = null;
            MemoryStream           ms     = null;

            Task commandSenderTask = Task.Run(async() => await commandSender(tokenSource.Token));

            try {
                ms = new MemoryStream();

                do
                {
                    result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), tokenSource.Token);

                    await ms.WriteAsync(buffer, 0, result.Count, tokenSource.Token);

                    // if total message received -> process it
                    if (result.EndOfMessage && (!result.CloseStatus.HasValue))
                    {
                        ms.Seek(0, SeekOrigin.Begin);

                        if (result.MessageType == WebSocketMessageType.Text)
                        {
                            using (var reader = new StreamReader(ms, Encoding.UTF8)) {
                                await processResult(await reader.ReadToEndAsync());                                 // start task without wait
                            }
                        }

                        ms.Dispose();
                        ms = new MemoryStream();
                    }
                } while (!result.CloseStatus.HasValue);

                Console.WriteLine("Closing... ");

                await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, tokenSource.Token);

                // will cancel commandSenderTask
                tokenSource.Cancel();

                await commandSenderTask;
            } catch (Exception e) {
                Console.WriteLine("Exception: " + e.Message + "\n" + e.StackTrace);
            } finally {
                ms?.Dispose();
                messageQueue?.Dispose();
                webSocket?.Abort();
                tokenSource?.Dispose();
            }
        }
コード例 #19
0
        public async Task ProcessSocketAsync(WebSocket socket)
        {
            // Begin sending and receiving. Receiving must be started first because ExecuteAsync enables SendAsync.
            var receiving = StartReceiving(socket);
            var sending   = StartSending(socket);

            // Wait for something to shut down.
            var trigger = await Task.WhenAny(
                receiving,
                sending);

            var failed = trigger.IsCanceled || trigger.IsFaulted;
            var task   = Task.CompletedTask;

            if (trigger == receiving)
            {
                task = sending;
                _logger.WaitingForSend(_connection.ConnectionId);
            }
            else
            {
                task = receiving;
                _logger.WaitingForClose(_connection.ConnectionId);
            }

            // We're done writing
            _application.Writer.TryComplete();

            await socket.CloseOutputAsync(failed?WebSocketCloseStatus.InternalServerError : WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);

            var resultTask = await Task.WhenAny(task, Task.Delay(_options.CloseTimeout));

            if (resultTask != task)
            {
                _logger.CloseTimedOut(_connection.ConnectionId);
                socket.Abort();
            }
            else
            {
                // Observe any exceptions from second completed task
                task.GetAwaiter().GetResult();
            }

            // Observe any exceptions from original completed task
            trigger.GetAwaiter().GetResult();
        }
コード例 #20
0
            async Task CloseOrAbortWebSocketAsync(
                Task <WebSocket> connectTask,
                bool abort,
                WebSocketCloseStatus closeStatus    = WebSocketCloseStatus.Empty,
                string statusDescription            = null,
                CancellationToken cancellationToken = default(CancellationToken))
            {
                Fx.Assert(connectTask != null, "CloseWebSocketAsync was called with null connectTask");
                Fx.Assert(connectTask.IsCompleted || !abort, "CloseOrAbortWebSocketAsync(abort=true) should only be called with a completed connectTask");
                lock (this.ThisLock)
                {
                    if (object.ReferenceEquals(connectTask, this.connectAsyncTask))
                    {
                        this.connectAsyncTask = null;
                    }
                }

                WebSocket webSocket = null;

                try
                {
                    webSocket = await connectTask.ConfigureAwait(false);

                    if (abort)
                    {
                        webSocket.Abort();
                    }
                    else
                    {
                        await webSocket.CloseOutputAsync(closeStatus, statusDescription, cancellationToken).ConfigureAwait(false);

                        await webSocket.CloseAsync(closeStatus, statusDescription, cancellationToken).ConfigureAwait(false);
                    }
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }

                    RelayEventSource.Log.HandledExceptionAsWarning(this.listener, e);
                    webSocket?.Abort();
                }
            }
コード例 #21
0
        private static async Task <bool> WriteToSocket(byte[] buffer, WebSocket socket, CancellationToken cancellationToken = default)
        {
            if (socket?.State == WebSocketState.Open)
            {
                try
                {
                    await socket.SendAsync(buffer, WebSocketMessageType.Text, true, cancellationToken).ConfigureAwait(false);

                    return(true);
                }
                catch// (System.Net.WebSockets.WebSocketException ex)
                {
                    socket.Abort();
                    socket.Dispose();
                }
            }
            return(false);
        }
コード例 #22
0
        private async Task Receive(WebSocket webSocket, Action <WebSocketReceiveResult, string> handleMessage)
        {
            while (webSocket.State == WebSocketState.Open)
            {
                try
                {
                    string message = null;
                    WebSocketReceiveResult result = null;
                    ArraySegment <byte>    buffer = new ArraySegment <byte>(new byte[1024 * 4]);

                    using (var ms = new MemoryStream())
                    {
                        do
                        {
                            result = await webSocket.ReceiveAsync(buffer, CancellationToken.None).ConfigureAwait(false);

                            ms.Write(buffer.Array, buffer.Offset, result.Count);
                        }while (!result.EndOfMessage);

                        ms.Seek(0, SeekOrigin.Begin);

                        using (var reader = new StreamReader(ms, Encoding.UTF8))
                        {
                            message = await reader.ReadToEndAsync().ConfigureAwait(false);
                        }
                    }

                    if (result.MessageType != WebSocketMessageType.Close)
                    {
                        handleMessage(result, message);
                    }
                }
                catch (WebSocketException e)
                {
                    if (e.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely)
                    {
                        webSocket.Abort();
                    }
                }
            }

            //await _webSocketHandler.OnDisconnected(socket);
        }
コード例 #23
0
 private async Task RunSafeDaemon(Func <Task> toRun)
 {
     try {
         while (!disposed)
         {
             await toRun();
         }
     } catch (Exception e) {
         if (!disposed && Socket.State == WebSocketState.Open)
         {
             SendBytes sb = new SendBytes(() => Task.FromResult(Socket));
             sb.Exception = e;
             await sb.AwaitFlowControl();
         }
     } finally {
         Socket.Abort();
         Dispose();
     }
 }
コード例 #24
0
        private async Task WebSocketRequest(AspNetWebSocketContext context)
        {
            Debug.WriteLine("2");
            Locker.EnterWriteLock();
            try
            {
                socket = context.WebSocket;
            }
            finally
            {
                Locker.ExitWriteLock();
            }

            while (true)
            {
                var buffer = new ArraySegment <byte>(Encoding.UTF8.GetBytes(DateTime.Now.ToLongTimeString()));
                Debug.WriteLine("3");
                Thread.Sleep(3000);

                try
                {
                    if (socket.State == WebSocketState.Open)
                    {
                        Debug.WriteLine("4");
                        await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                    }
                }

                catch (ObjectDisposedException)
                {
                    Locker.EnterWriteLock();
                    try
                    {
                        socket.Abort();
                    }
                    finally
                    {
                        Locker.ExitWriteLock();
                    }
                }
            }
        }
コード例 #25
0
            async Task HandleListenerContextAsync(HttpListenerContext context)
            {
                WebSocket webSocket = null;

                try
                {
                    var wsContext = await context.AcceptWebSocketAsync(WebSocketTransport.WebSocketSubProtocol);

                    var wsTransport = new WebSocketTransport(wsContext.WebSocket);
                    await this.listener.HandleTransportAsync(wsTransport);
                }
                catch (Exception exception)
                {
                    Trace.WriteLine(TraceLevel.Error, exception.ToString());
                    if (webSocket != null)
                    {
                        webSocket.Abort();
                    }
                }
            }
コード例 #26
0
        /// <summary>
        /// Обработка сообщений от подключившегося клиента
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        protected override async Task SocketHandlerAsync(WebSocket socket, CancellationToken cancellationToken = default)
        {
            if (socket is null)
            {
                throw new ArgumentNullException(nameof(socket));
            }

            try
            {
                var buffer = new ArraySegment <byte>(new byte[16384]);
                //if (socket.State == WebSocketState.Open)
                while ((socket.State == WebSocketState.Open) && (!cancellationToken.IsCancellationRequested))
                {
                    var req = await socket.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false);

                    //while (!req.EndOfMessage)
                    //    await socket.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false);

                    if ((socket.State != WebSocketState.Open) || (cancellationToken.IsCancellationRequested))
                    {
                        break;
                    }

                    var respBytes = await router.Handle(buffer.Array, 0, req.Count).ConfigureAwait(false);

                    if ((socket.State != WebSocketState.Open) || (cancellationToken.IsCancellationRequested))
                    {
                        break;
                    }

                    await socket.SendAsync(respBytes, WebSocketMessageType.Text, true, cancellationToken).ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.TraceError($"{nameof(WebSocketRpcServer)}.SocketHandlerAsync(): {ex.InnerMessage()}");
            }

            socket.Abort();
            socket.Dispose();
        }
コード例 #27
0
        private async Task ProcessAsync()
        {
            try
            {
                _receiveQueue.Out.PropagateCompletionFrom(TaskRunner.RunInBackground(ReceiveInternalAsync));
                var sendTask = SendInternalAsync();
                await Task
                .WhenAny(
                    sendTask,
                    _receiveQueue.In.Completion)
                .Unwrap()
                .ConfigureAwait(false);

                await Task
                .WhenAll(
                    sendTask,
                    _receiveQueue.In.Completion)
                .ConfigureAwait(false);

                _log.Trace("Closing socket");
                await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None).ConfigureAwait(false);
            }
            catch
            {
                try
                {
                    await _webSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, "", CancellationToken.None).ConfigureAwait(false);
                }
                catch
                {
                    try
                    {
                        _webSocket.Abort();
                    }
                    catch
                    {
                    }
                }
                throw;
            }
        }
コード例 #28
0
        public override async void OnConnected(WebSocket socket, HttpContext context)
        {
            var user = _am.Authenticate(context);

            if (user == null)
            {
                socket.Abort(); return;
            }
            base.OnConnected(socket, context);
            var socketUser = new SocketUser(user, _cm, socket);

            AllConnectedUsers.TryAdd(socket, socketUser);
            foreach (var c in socketUser.SubscribedChannels)
            {
                Channels.TryGetValue(c.Id, out SocketChannel channel);
                channel.JoinChannel(socketUser);
            }

            var socketId = WSManager.GetId(socket);

            await SendMessageToAllAsync("{ \"type\": \"USERCONNECTED\", \"message\":\"" + user.Email + " is now connected\"}");
        }
コード例 #29
0
        internal async Task CleanupAsync()
        {
            switch (_webSocket.State)
            {
            case WebSocketState.Closed:     // Closed gracefully, no action needed.
            case WebSocketState.Aborted:    // Closed abortively, no action needed.
                break;

            case WebSocketState.CloseReceived:
                // Echo what the client said, if anything.
                await _webSocket.CloseAsync(_webSocket.CloseStatus ?? WebSocketCloseStatus.NormalClosure,
                                            _webSocket.CloseStatusDescription ?? string.Empty, _cancellationToken);

                break;

            case WebSocketState.Open:
            case WebSocketState.CloseSent:     // No close received, abort so we don't have to drain the pipe.
                _webSocket.Abort();
                break;

            default:
                throw new ArgumentOutOfRangeException("state", _webSocket.State, string.Empty);
            }
        }
コード例 #30
0
        public async Task ProcessSocketAsync(WebSocket socket)
        {
            // Begin sending and receiving. Receiving must be started first because ExecuteAsync enables SendAsync.
            var receiving = StartReceiving(socket);
            var sending   = StartSending(socket);

            // Wait for send or receive to complete
            var trigger = await Task.WhenAny(receiving, sending);

            if (trigger == receiving)
            {
                Log.WaitingForSend(_logger);

                // We're waiting for the application to finish and there are 2 things it could be doing
                // 1. Waiting for application data
                // 2. Waiting for a websocket send to complete

                // Cancel the application so that ReadAsync yields
                _application.Input.CancelPendingRead();

                using (var delayCts = new CancellationTokenSource())
                {
                    var resultTask = await Task.WhenAny(sending, Task.Delay(_options.CloseTimeout, delayCts.Token));

                    if (resultTask != sending)
                    {
                        // We timed out so now we're in ungraceful shutdown mode
                        Log.CloseTimedOut(_logger);

                        // Abort the websocket if we're stuck in a pending send to the client
                        _aborted = true;

                        socket.Abort();
                    }
                    else
                    {
                        delayCts.Cancel();
                    }
                }
            }
            else
            {
                Log.WaitingForClose(_logger);

                // We're waiting on the websocket to close and there are 2 things it could be doing
                // 1. Waiting for websocket data
                // 2. Waiting on a flush to complete (backpressure being applied)

                using (var delayCts = new CancellationTokenSource())
                {
                    var resultTask = await Task.WhenAny(receiving, Task.Delay(_options.CloseTimeout, delayCts.Token));

                    if (resultTask != receiving)
                    {
                        // Abort the websocket if we're stuck in a pending receive from the client
                        _aborted = true;

                        socket.Abort();

                        // Cancel any pending flush so that we can quit
                        _application.Output.CancelPendingFlush();
                    }
                    else
                    {
                        delayCts.Cancel();
                    }
                }
            }
        }