private void SendToWebSockets(WebSocketMessageEntry item, ArraySegment <byte> bytes) { if (_tasks.Length != item.WebSocketsList.Count) { Array.Resize(ref _tasks, item.WebSocketsList.Count); } for (int i = 0; i < item.WebSocketsList.Count; i++) { var socket = item.WebSocketsList[i]; try { _tasks[i] = socket.SendAsync(bytes, WebSocketMessageType.Text, true, CancellationToken.None); } catch (Exception) { RemoveWebSocket(socket); } } bool success; try { success = Task.WaitAll(_tasks, 250); } catch (Exception) { success = false; } if (success == false) { for (int i = 0; i < _tasks.Length; i++) { if (_tasks[i].IsFaulted || _tasks[i].IsCanceled || _tasks[i].IsCompleted == false) { // this either timed out or errored, removing it. RemoveWebSocket(item.WebSocketsList[i]); } } } }
private int ActualWriteToLogTargets(WebSocketMessageEntry item, Stream file) { item.Data.TryGetBuffer(out var bytes); file.Write(bytes.Array, bytes.Offset, bytes.Count); _additionalOutput?.Write(bytes.Array, bytes.Offset, bytes.Count); if (item.Task != null) { try { file.Flush(); _additionalOutput?.Flush(); } finally { item.Task.TrySetResult(null); } } try { _pipeSink?.Write(bytes.Array, bytes.Offset, bytes.Count); } catch { // broken pipe } if (!_listeners.IsEmpty) { // this is rare SendToWebSockets(item, bytes); } item.Data.SetLength(0); item.WebSocketsList.Clear(); return(bytes.Count); }
public void Log(ref LogEntry entry, TaskCompletionSource <object> tcs = null) { var state = _localState.Value; if (state.Generation != _generation) { _localState.Value = GenerateThreadWriterState(); } if (state.Free.Dequeue(out var item)) { item.Data.SetLength(0); item.WebSocketsList.Clear(); item.Task = tcs; state.ForwardingStream.Destination = item.Data; } else { item = new WebSocketMessageEntry(); item.Task = tcs; state.ForwardingStream.Destination = new MemoryStream(); } foreach (var kvp in _listeners) { if (kvp.Value.Filter.Forward(ref entry)) { item.WebSocketsList.Add(kvp.Key); } } WriteEntryToWriter(state.Writer, ref entry); item.Data = state.ForwardingStream.Destination; state.Full.Enqueue(item, timeout: 128); _hasEntries.Set(); }