예제 #1
0
        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]);
                    }
                }
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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();
        }