コード例 #1
0
        /// <summary>
        /// Construct a TCP _socket writer that writes to the given endPoint and _port.
        /// </summary>
        /// <param name="uri">Uri to open a TCP socket to.</param>
        /// <param name="maxQueueSize">The maximum number of log entries to queue before starting to drop entries.</param>
        public TcpSocketWriter(Uri uri, int maxQueueSize = 5000)
        {
            _eventQueue  = new FixedSizeQueue <string>(maxQueueSize);
            _tokenSource = new CancellationTokenSource();

            Func <Uri, Task <Stream> > tryOpenSocket = async h =>
            {
                try
                {
                    TcpClient client = new TcpClient();
                    await client.ConnectAsync(uri.Host, uri.Port);

                    Stream stream = client.GetStream();
                    if (uri.Scheme.ToLower() != "tls")
                    {
                        return(stream);
                    }

                    var sslStream = new SslStream(client.GetStream(), false, null, null);
                    await sslStream.AuthenticateAsClientAsync(uri.Host);

                    return(sslStream);
                }
                catch (Exception e)
                {
                    LoggingFailureHandler(e);
                    throw;
                }
            };

            var threadReady = new TaskCompletionSource <bool>();

            Task queueListener = Task.Factory.StartNew(async() =>
            {
                try
                {
                    bool sslEnabled = uri.Scheme.ToLower() == "tls";
                    _stream         = await _reconnectPolicy.ConnectAsync(tryOpenSocket, uri, _tokenSource.Token);
                    threadReady.SetResult(true); // Signal the calling thread that we are ready.

                    string entry = null;
                    while (_stream != null) // null indicates that the thread has been cancelled and cleaned up.
                    {
                        if (_tokenSource.Token.IsCancellationRequested)
                        {
                            _eventQueue.CompleteAdding();
                            // Post-condition: no further items will be added to the queue, so there will be a finite number of items to handle.
                            while (_eventQueue.Count > 0)
                            {
                                entry = _eventQueue.Dequeue();
                                try
                                {
                                    byte[] messsage = Encoding.UTF8.GetBytes(entry);
                                    await _stream.WriteAsync(messsage, 0, messsage.Length);
                                    await _stream.FlushAsync();
                                }
                                catch (SocketException ex)
                                {
                                    LoggingFailureHandler(ex);
                                }
                            }
                            break;
                        }
                        if (entry == null)
                        {
                            entry = _eventQueue.Dequeue(_tokenSource.Token);
                        }
                        else
                        {
                            try
                            {
                                byte[] messsage = Encoding.UTF8.GetBytes(entry);
                                await _stream.WriteAsync(messsage, 0, messsage.Length);
                                await _stream.FlushAsync();
                                // No exception, it was sent
                                entry = null;
                            }
                            catch (IOException ex)
                            {
                                LoggingFailureHandler(ex);
                                _stream = await _reconnectPolicy.ConnectAsync(tryOpenSocket, uri, _tokenSource.Token);
                            }
                            catch (SocketException ex)
                            {
                                LoggingFailureHandler(ex);
                                _stream = await _reconnectPolicy.ConnectAsync(tryOpenSocket, uri, _tokenSource.Token);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    LoggingFailureHandler(e);
                }
                finally
                {
                    if (_stream != null)
                    {
                        _stream.Dispose();
                    }

                    _disposed.SetResult(true);
                }
            }, _tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);

            threadReady.Task.Wait(TimeSpan.FromSeconds(5));
        }
コード例 #2
0
        /// <summary>
        /// Construct a TCP _socket writer that writes to the given endPoint and _port.
        /// </summary>
        /// <param name="uri">Uri to open a TCP socket to.</param>
        /// <param name="maxQueueSize">The maximum number of log entries to queue before starting to drop entries.</param>
        public TcpSocketWriter(Uri uri, int maxQueueSize = 5000)
        {
            _eventQueue  = new FixedSizeQueue <string>(maxQueueSize);
            _tokenSource = new CancellationTokenSource();

            Func <Uri, Stream> tryOpenSocket = h =>
            {
                try
                {
                    TcpClient client = new TcpClient(uri.Host, uri.Port);
                    Stream    stream = client.GetStream();
                    if (uri.Scheme.ToLower() != "tls")
                    {
                        return(stream);
                    }

                    var sslStream = new SslStream(client.GetStream(), false, null, null);
                    sslStream.AuthenticateAsClient(uri.Host);
                    return(sslStream);
                }
                catch (SocketException e)
                {
                    LoggingFailureHandler(e);
                    throw;
                }
            };

            var threadReady = new TaskCompletionSource <bool>();

            var queueListener = new Thread(() =>
            {
                try
                {
                    _stream = _reconnectPolicy.Connect(tryOpenSocket, uri, _tokenSource.Token);
                    threadReady.SetResult(true); // Signal the calling thread that we are ready.

                    string entry = null;
                    while (_stream != null) // null indicates that the thread has been cancelled and cleaned up.
                    {
                        if (_tokenSource.Token.IsCancellationRequested)
                        {
                            _eventQueue.CompleteAdding();
                            // Post-condition: no further items will be added to the queue, so there will be a finite number of items to handle.
                            while (_eventQueue.Count > 0)
                            {
                                entry = _eventQueue.Dequeue();
                                try
                                {
                                    var messsage = Encoding.UTF8.GetBytes(entry);
                                    if (uri.Scheme.ToLower() == "tls")
                                    {
                                        ((SslStream)_stream).Write(messsage);
                                    }
                                    else
                                    {
                                        _stream.Write(messsage, 0, messsage.Length);
                                        _stream.Flush();
                                    }
                                }
                                catch (SocketException ex)
                                {
                                    LoggingFailureHandler(ex);
                                }
                            }
                            break;
                        }
                        if (entry == null)
                        {
                            entry = _eventQueue.Dequeue(_tokenSource.Token);
                        }
                        else
                        {
                            try
                            {
                                var messsage = Encoding.UTF8.GetBytes(entry);
                                if (uri.Scheme.ToLower() == "tls")
                                {
                                    ((SslStream)_stream).Write(messsage);
                                }
                                else
                                {
                                    _stream.Write(messsage, 0, messsage.Length);
                                }
                                _stream.Flush();
                                // No exception, it was sent
                                entry = null;
                            }
                            catch (SocketException ex)
                            {
                                LoggingFailureHandler(ex);
                                _stream = _reconnectPolicy.Connect(tryOpenSocket, uri, _tokenSource.Token);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    LoggingFailureHandler(e);
                }
                finally
                {
                    if (_stream != null)
                    {
                        _stream.Close();
                        _stream.Dispose();
                    }

                    _disposed.SetResult(true);
                }
            })
            {
                IsBackground = true
            };

            // Prevent the thread from blocking the process from exiting.
            queueListener.Start();
            threadReady.Task.Wait(TimeSpan.FromSeconds(5));
        }