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(); } } }
public void Dispose() { if (!_socket.CloseStatus.HasValue) { _socket.Abort(); } }
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); } }
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(); } } } }
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); }
/// <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(); } }
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); } }
/// <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(); }
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()); } }
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, }); } }
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; } } }
private void Close() { try { Socket.Abort(); } catch (Exception) { } }
public void AbortConnection(Guid connectionid) { WebSocket ws = null; if (!_clients.TryGetValue(connectionid, out ws)) { return; } ws.Abort(); }
public override void Abort() { if (state == disposed) { return; } if (innerWebSocket != null) { innerWebSocket.Abort(); } Dispose(); }
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)); }
/// <inheritdoc/> public override void Disconnect() { try { _webSocket.Abort(); _clientDisconnectedHandler(this); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}."); } }
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()}"); } }
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(); } }
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(); }
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(); } }
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); }
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); }
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(); } }
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(); } } } }
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(); } } }
/// <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(); }
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; } }
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\"}"); }
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); } }
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(); } } } }