Example #1
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;
            }
        }
        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;
        }