private async Task <bool> MessageWriteAsync(ClientMetadata md, byte[] data, WebSocketMessageType msgType) { string header = "[WatsonWsServer " + md.IpPort + "] "; try { #region Send-Message // Cannot have two simultaneous SendAsync calls so use a // semaphore to block the second until the first has completed await md.SendLock.WaitAsync(md.TokenSource.Token); try { await md.Ws.SendAsync(new ArraySegment <byte>(data, 0, data.Length), msgType, true, md.TokenSource.Token); } finally { md.SendLock.Release(); } _Stats.IncrementSentMessages(); _Stats.AddSentBytes(data.Length); return(true); #endregion } catch (OperationCanceledException oce) { Logger?.Invoke(header + "disconnected (canceled): " + oce.Message); } catch (WebSocketException wse) { Logger?.Invoke(header + "disconnected (websocket exception): " + wse.Message); } catch (Exception e) { Logger?.Invoke(header + "disconnected due to exception: " + Environment.NewLine + e.ToString()); } return(false); }
private async Task <bool> MessageWriteAsync(byte[] data, WebSocketMessageType msgType, CancellationToken token) { bool disconnectDetected = false; using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_Token, token)) { try { if (_ClientWs == null || _ClientWs.State != WebSocketState.Open) { Logger?.Invoke(_Header + "not connected"); disconnectDetected = true; return(false); } await _SendLock.WaitAsync(_Token); try { await _ClientWs.SendAsync(new ArraySegment <byte>(data, 0, data.Length), msgType, true, token); } catch { } finally { _SendLock.Release(); } if (EnableStatistics) { _Stats.IncrementSentMessages(); _Stats.AddSentBytes(data.Length); } return(true); } catch (TaskCanceledException) { if (_Token.IsCancellationRequested) { Logger?.Invoke(_Header + "canceled"); disconnectDetected = true; } else if (token.IsCancellationRequested) { Logger?.Invoke(_Header + "message send canceled"); } return(false); } catch (OperationCanceledException) { if (_Token.IsCancellationRequested) { Logger?.Invoke(_Header + "canceled"); disconnectDetected = true; } else if (token.IsCancellationRequested) { Logger?.Invoke(_Header + "message send canceled"); } return(false); } catch (WebSocketException) { Logger?.Invoke(_Header + "websocket disconnected"); disconnectDetected = true; return(false); } catch (ObjectDisposedException) { Logger?.Invoke(_Header + "disposed"); disconnectDetected = true; return(false); } catch (SocketException) { Logger?.Invoke(_Header + "socket disconnected"); disconnectDetected = true; return(false); } catch (InvalidOperationException) { Logger?.Invoke(_Header + "disconnected due to invalid operation"); disconnectDetected = true; return(false); } catch (IOException) { Logger?.Invoke(_Header + "IO disconnected"); disconnectDetected = true; return(false); } catch (Exception e) { Logger?.Invoke(_Header + "exception: " + Environment.NewLine + e.ToString()); disconnectDetected = true; return(false); } finally { if (disconnectDetected) { Dispose(); ServerDisconnected?.Invoke(this, EventArgs.Empty); InternalServerDisconnected?.Invoke(this, EventArgs.Empty); } } } }
private async Task <bool> MessageWriteAsync(ClientMetadata md, byte[] data, WebSocketMessageType msgType, CancellationToken token) { string header = "[WatsonWsServer " + md.IpPort + "] "; CancellationToken[] tokens = new CancellationToken[3]; tokens[0] = _Token; tokens[1] = token; tokens[2] = md.TokenSource.Token; using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(tokens)) { try { #region Send-Message await md.SendLock.WaitAsync(md.TokenSource.Token).ConfigureAwait(false); try { await md.Ws.SendAsync(new ArraySegment <byte>(data, 0, data.Length), msgType, true, linkedCts.Token).ConfigureAwait(false); } finally { md.SendLock.Release(); } _Stats.IncrementSentMessages(); _Stats.AddSentBytes(data.Length); return(true); #endregion } catch (TaskCanceledException) { if (_Token.IsCancellationRequested) { Logger?.Invoke(header + "server canceled"); } else if (token.IsCancellationRequested) { Logger?.Invoke(header + "message send canceled"); } else if (md.TokenSource.Token.IsCancellationRequested) { Logger?.Invoke(header + "client canceled"); } } catch (OperationCanceledException) { if (_Token.IsCancellationRequested) { Logger?.Invoke(header + "canceled"); } else if (token.IsCancellationRequested) { Logger?.Invoke(header + "message send canceled"); } else if (md.TokenSource.Token.IsCancellationRequested) { Logger?.Invoke(header + "client canceled"); } } catch (ObjectDisposedException) { Logger?.Invoke(header + "disposed"); } catch (WebSocketException) { Logger?.Invoke(header + "websocket disconnected"); } catch (SocketException) { Logger?.Invoke(header + "socket disconnected"); } catch (InvalidOperationException) { Logger?.Invoke(header + "disconnected due to invalid operation"); } catch (IOException) { Logger?.Invoke(header + "IO disconnected"); } catch (Exception e) { Logger?.Invoke(header + "exception: " + Environment.NewLine + e.ToString()); } } return(false); }