public async Task <T> ReceiveAsync <T>() where T : IAmqpMessage
        {
            var result = await _reader.ReadAsync(_formatter);

            _reader.Advance();
            return((T)result.Message);
        }
示例#2
0
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            if (connection is null)
            {
                throw new ArgumentNullException(nameof(connection));
            }

            using IDisposable loggerScope = _logger.BeginScope("Peer {PeerId} connected to server {ServerEndpoint}", connection.ConnectionId, connection.LocalEndPoint);

            ProtocolReader reader = connection.CreateReader();
            INetworkProtocolMessageSerializer protocol = _serviceProvider.GetRequiredService <INetworkProtocolMessageSerializer>();

            using IPeerContext peerContext = _peerContextFactory.CreateIncomingPeerContext(connection.ConnectionId,
                                                                                           connection.LocalEndPoint !.AsIPEndPoint().EnsureIPv6(),
                                                                                           connection.RemoteEndPoint !.AsIPEndPoint().EnsureIPv6(),
                                                                                           new NetworkMessageWriter(protocol, connection.CreateWriter()));

            using CancellationTokenRegistration cancellationRegistration = peerContext.ConnectionCancellationTokenSource.Token.Register(() =>
            {
                connection.Abort(new ConnectionAbortedException("Requested by PeerContext"));
            });

            connection.Features.Set(peerContext);
            protocol.SetPeerContext(peerContext);

            if (EnsurePeerCanConnect(connection, peerContext))
            {
                _eventBus.Publish(new PeerConnected(peerContext));

                await _networkMessageProcessorFactory.StartProcessorsAsync(peerContext).ConfigureAwait(false);

                while (true)
                {
                    try
                    {
                        ProtocolReadResult <INetworkMessage> result = await reader.ReadAsync(protocol).ConfigureAwait(false);

                        if (result.IsCompleted)
                        {
                            break;
                        }

                        await ProcessMessageAsync(result.Message, peerContext, connection.ConnectionClosed).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogDebug(ex, "Unexpected connection terminated because of {DisconnectionReason}.", ex.Message);
                        break;
                    }
                    finally
                    {
                        reader.Advance();
                    }
                }

                return;
            }
        }
示例#3
0
        private async Task <MemcachedResponse> ExecuteCommand(MemcachedRequest request)
        {
            await _protocolWriter.WriteAsync(_memcachedMessageWriter, request);

            var result = await _protocolReader.ReadAsync(_memcachedMessageReader);

            _protocolReader.Advance();
            return(result.Message);
        }
示例#4
0
        private async Task ProcessReadsAsync()
        {
            while (true)
            {
                var result = await _reader.ReadAsync(_protocol);

                var message = result.Message;

                if (result.IsCompleted || result.IsCanceled)
                {
                    break;
                }

                switch (message.MessageType)
                {
                case MessageType.Error:
                {
                    if (_operations.TryRemove(message.Id, out var operation))
                    {
                        if (message.Payload.Length > 0)
                        {
                            operation.TrySetException(new Exception(Encoding.UTF8.GetString(message.Payload.Span)));
                        }
                        else
                        {
                            operation.TrySetException(new Exception($"Operation {message.Id} failed"));
                        }
                    }
                }
                break;

                case MessageType.Success:
                {
                    if (_operations.TryRemove(message.Id, out var operation))
                    {
                        operation.TrySetResult(null);
                    }
                }
                break;

                case MessageType.Data:
                    if (_topics.TryGetValue(message.Topic, out var callback))
                    {
                        // REVIEW: This will deadlock if the client is used in the
                        // callback
                        await callback(message.Topic, message.Payload);
                    }
                    break;

                default:
                    break;
                }

                _reader.Advance();
            }
        }
示例#5
0
        internal async ValueTask <T> ReadAsync <T>(IMessageReader <T> reader, CancellationToken token = default)
        {
            var result = await _protocol.ReadAsync(reader, token).ConfigureAwait(false);

            _protocol.Advance();
            if (result.IsCanceled || result.IsCompleted)
            {
                //TODO: do something
            }

            return(result.Message);
        }
示例#6
0
        /// <summary>
        /// on connected as an asynchronous operation.
        /// </summary>
        /// <param name="connection">The new <see cref="T:Microsoft.AspNetCore.Connections.ConnectionContext" /></param>
        /// <returns>A <see cref="T:System.Threading.Tasks.Task" /> that represents the connection lifetime. When the task completes, the connection is complete.</returns>
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            this.context = connection;
            this.reader  = connection.CreateReader();
            this.writer  = connection.CreateWriter();

            SessionManager.Singleton.AcceptSession(connection, writer, this.protocol);

            //IConnectionHeartbeatFeature heartbeatFeature = connection.Features.Get<IConnectionHeartbeatFeature>();
            //heartbeatFeature.OnHeartbeat(this.SendHeartbeat, null);

            while (true)
            {
                try
                {
                    var result = await reader.ReadAsync(protocol);

                    var message = result.Message;

                    _logger.LogInformation("Received a message of {Length} bytes", message.Payload.Length);

                    if (result.IsCompleted)
                    {
                        break;
                    }



                    await writer.WriteAsync(protocol, message);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex.Message);
                    connection.Abort();
                    break;
                }
                finally
                {
                    reader.Advance();
                }
            }
        }
示例#7
0
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            this.EnsurePeerCanConnect(connection);

            // Use a length prefixed protocol
            var protocol = new NetworkMessageProtocol(this.loggerFactory.CreateLogger <NetworkMessageProtocol>(), this.chainDefinition);
            ProtocolReader <Message> reader = Protocol.CreateReader(connection, protocol);
            ProtocolWriter <Message> writer = Protocol.CreateWriter(connection, protocol);

            while (true)
            {
                Message message = await reader.ReadAsync();

                this.logger.LogInformation("Received a message of {Length} bytes", message.Payload.Length);

                await this.ParseMessage(message, connection).ConfigureAwait(false);

                // REVIEW: We need a ReadResult<T> to indicate completion and cancellation
                if (message.Payload == null)
                {
                    break;
                }
            }
        }
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            Logger.Debug($"Connecting to {_proxySettings.RemoteHost}:{_proxySettings.RemotePort}");
            var proxyClient = new TcpClient();
            await proxyClient.ConnectAsync(_proxySettings.RemoteHost, _proxySettings.RemotePort);

            var ogStream = proxyClient.GetStream();

            Stream proxyStream = ogStream;

            if (_proxySettings.Secure)
            {
                var protocol = new TlsClientProtocol(proxyStream, new Org.BouncyCastle.Security.SecureRandom());
                protocol.Connect(new BlazeTlsClient());
                proxyStream = protocol.Stream;
            }

            var blazeProtocol = new BlazeProxyProtocol();
            var localReader   = connection.CreateReader();
            var localWriter   = connection.CreateWriter();

            var remoteReader = new ProtocolReader(proxyStream);
            var remoteWriter = new ProtocolWriter(proxyStream);


            while (true)
            {
                try
                {
                    var result = await localReader.ReadAsync(blazeProtocol);

                    var message = result.Message;

                    if (message != null)
                    {
                        var header = message.Header;
                        Logger.Debug(
                            $"Client -> Proxy; Length:{header.Length} Component:{header.Component} Command:0x{header.Command:X2} ErrorCode:{header.ErrorCode} MessageType:{header.MessageType} MessageId:{header.MessageId}");

                        var requestPayload = message.Payload;

                        if (!requestPayload.IsEmpty)
                        {
                            if (!_parser.TryParseBody(requestPayload))
                            {
                                Logger.Error("Failed to parse request message");
                            }
                        }

                        await remoteWriter.WriteAsync(blazeProtocol, message);
                    }

                    if (result.IsCompleted)
                    {
                        break;
                    }
                }
                finally
                {
                    localReader.Advance();
                }

                do
                {
                    try
                    {
                        var result = await remoteReader.ReadAsync(blazeProtocol);

                        var message = result.Message;

                        if (message != null)
                        {
                            var header = message.Header;
                            Logger.Debug(
                                $"Proxy <- Server; Length:{header.Length} Component:{header.Component} Command:0x{header.Command:X2} ErrorCode:{header.ErrorCode} MessageType:{header.MessageType} MessageId:{header.MessageId}");

                            var responsePayload = message.Payload;

                            if (!responsePayload.IsEmpty)
                            {
                                if (!_parser.TryParseBody(responsePayload))
                                {
                                    Logger.Error("Failed to parse response message");
                                }
                            }

                            await localWriter.WriteAsync(blazeProtocol, message);
                        }

                        if (result.IsCompleted)
                        {
                            break;
                        }
                    }
                    finally
                    {
                        remoteReader.Advance();
                    }
                } while (ogStream.DataAvailable);
            }
        }
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            // TODO: we could register processors as Scoped per connection and create a scope here
            //using var serviceProviderScope = serviceProvider.CreateScope();

            if (connection is null)
            {
                throw new ArgumentNullException(nameof(connection));
            }

            using IDisposable logScope = _logger.BeginScope("Peer {PeerId} connected to outbound {PeerEndpoint}", connection.ConnectionId, connection.LocalEndPoint);

            ProtocolReader reader = connection.CreateReader();
            INetworkProtocolMessageSerializer protocol = _serviceProvider.GetRequiredService <INetworkProtocolMessageSerializer>();

            using IPeerContext peerContext = _peerContextFactory.CreateOutgoingPeerContext(connection.ConnectionId,
                                                                                           connection.LocalEndPoint !,
                                                                                           connection.Features.Get <OutgoingConnectionEndPoint>(),
                                                                                           new NetworkMessageWriter(protocol, connection.CreateWriter()));

            connection.ConnectionClosed = peerContext.ConnectionCancellationTokenSource.Token;
            connection.Features.Set(peerContext);

            protocol.SetPeerContext(peerContext);

            _eventBus.Publish(new PeerConnected(peerContext));


            await _networkMessageProcessorFactory.StartProcessorsAsync(peerContext).ConfigureAwait(false);


            while (true)
            {
                if (connection.ConnectionClosed.IsCancellationRequested)
                {
                    break;
                }

                try
                {
                    ProtocolReadResult <INetworkMessage> result =
                        await reader.ReadAsync(protocol, connection.ConnectionClosed).ConfigureAwait(false);

                    if (result.IsCompleted)
                    {
                        break;
                    }

                    await ProcessMessageAsync(result.Message, peerContext, connection.ConnectionClosed)
                    .WithCancellationAsync(connection.ConnectionClosed)
                    .ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (Exception e)
                {
                    _logger.LogError(new EventId(0), e, e.Message);
                    throw;
                }
                finally
                {
                    reader.Advance();
                }
            }

            return;
        }