Ejemplo n.º 1
0
        async Task Impl(ITcpClient client)
        {
            using (client)
                using (var networkActivityWatchDog = _tcpWatchDog.Watch(client))
                {
                    ApplyTcpSettings(client, _tcpSettings);

                    Stream stream = client.GetStream();

                    // Wrap with SSL, if required.
                    var t = await _sslService.WrapSslAsync(client, stream);

                    if (t != null)
                    {
                        stream = t;
                    }

                    // Get the raw tcp stream.
                    // For better exception handling and tracking of idle session,
                    // we wrap it with our custom TcpStream.
                    stream = (Stream) new TcpExceptionStreamDecorator(
                        new WatchDogStreamDecorator(stream, networkActivityWatchDog));

                    // Create a TCP session and execute it
                    var session = _tcpSessionFactory.Create(client, stream);
                    try
                    {
                        await session.ExecuteAsync();
                    }
                    finally
                    {
                        _tcpSessionFactory.Destroy(session);
                    }
                }
        }
Ejemplo n.º 2
0
        public async Task HandleAsync(IWebSocketRemoteDevice device)
        {
            var buff           = new ArraySegment <byte>(new byte[BUFFER_SIZE]);
            var messageBuilder = new StringBuilder();

            using var watcher = _watchDog.Watch(device);

            // Keep reading messages forever
            while (true)
            {
                // For each message received, we'll
                // update the watchdog so it won't stall.
                watcher.Refresh();

                // Read chunks of a message
                while (true)
                {
                    WebSocketReceiveResult tmp;
                    try
                    {
                        tmp = await device.WebSocketClient.WebSocketContext.WebSocket.ReceiveAsync(buff, CancellationToken.None);
                    }
                    // When the WebSocketClient is disposed
                    // by some other thread, it will throw InvalidOperationException
                    catch (Exception ex) when(ex is InvalidOperationException || ex is WebSocketException)
                    {
                        throw new IOException(ex.Message, ex);
                    }

                    if (tmp.MessageType == WebSocketMessageType.Close)
                    {
                        return;
                    }
                    if (tmp.MessageType != WebSocketMessageType.Text)
                    {
                        throw new NotSupportedException();
                    }
                    if (tmp.Count > 0 && tmp.MessageType == WebSocketMessageType.Text)
                    {
                        messageBuilder.Append(Encoding.UTF8.GetString(buff.Array, 0, tmp.Count));
                    }
                    if (tmp.EndOfMessage)
                    {
                        break;
                    }
                }

                // At this point, fully got the message;
                // Just pass it to the handler
                try
                {
                    await _commandHandler.HandleAsync(device, messageBuilder.ToString());
                }
                finally
                {
                    messageBuilder.Clear();
                }
            }
        }
Ejemplo n.º 3
0
        public void Register(IDisposable connection)
        {
            if (connection == null)
            {
                throw new ArgumentNullException(nameof(connection));
            }

            // Can we add?
            if (false == CanRegister(connection))
            {
                throw new InvalidOperationException("Already registered");
            }

            bool didAdd = false;

            // As we are calling external code within lock,
            // Let's enter the lock with a proper timeout.
            if (false == Monitor.TryEnter(_sync, TimeSpan.FromSeconds(15)))
            {
                throw new Exception("Potentially deadlock");
            }
            try
            {
                if (_watchedConnections.ContainsKey(connection))
                {
                    throw new InvalidOperationException("Already registered");
                }
                _watchedConnections[connection] = _watchDog.Watch(connection);
                didAdd = true;
            } finally {
                Monitor.Exit(_sync);
            }

            // Increase the count in case of a successful add.
            if (didAdd)
            {
                Interlocked.Increment(ref _total);
            }
        }