Пример #1
0
        public IEnumerable <PeerContext> GetPeerContexts(int uid)
        {
            if (0 == _cookie)
            {
                return(null);
            }

            try
            {
                var serverContext = this.ServerContext;
                var relations     = new List <ulong>();
                if (!serverContext.GetRelation(uid, ref relations))
                {
                    return(null);
                }

                var         list        = new List <PeerContext>();
                PeerContext peerContext = null;
                relations.ForEach(r =>
                {
                    peerContext = serverContext.GetPeerContext(r);
                    if (null != peerContext)
                    {
                        list.Add(peerContext);
                    }
                });

                return(list);
            }
            catch
            {
                throw;
            }
        }
Пример #2
0
        private void SearchTemplatesMatchingMessageAndHandle(Message message, PeerContext peerContext)
        {
            var rand = new Random();

            foreach (RegexToActionTemplate matchingTemplate in
                     //работа происходит с копией коллекции, поскольку оригинальная может быть изменена callback'ом
                     this.TemplateManager.SearchTemplatesMatchingMessage(message).ToList())
            {
                if (matchingTemplate.Callback == null)
                {
                    //TODO: make this call async
                    Api.Messages.Send(new MessagesSendParams
                    {
                        Message  = matchingTemplate.GetRandomResponseMessage(),
                        PeerId   = message.PeerId,
                        RandomId = rand.Next(1, Int32.MaxValue),
                        Keyboard = matchingTemplate.MessageKeyboard
                    });
                }
                else
                {
                    matchingTemplate.Callback(this, new MessageReceivedEventArgs(message, peerContext));
                }
            }
        }
Пример #3
0
        public override PeerBase CreatePeer(PeerContext peerContext)
        {
            var peertype = Encoding.UTF8.GetString(peerContext.ApplicationData);

            if (peertype == "udppeer")
            {
                return(new TestUdpPeer(peerContext));
            }
            else if (peertype == "kcppeer")
            {
                return(new BigBuffPeer(peerContext));
            }
            else if (peertype == "mixpeer")
            {
                return(new ExPeer(peerContext));
            }
            else if (peertype == "kcppeerflush")
            {
                return(new BigBuffPeerFlush(peerContext));
            }
            else
            {
                Console.WriteLine($"NotImplementedPeer");
                return(null);
            }
        }
Пример #4
0
        public async ValueTask AttachAsync(IPeerContext peerContext)
        {
            PeerContext    = peerContext as ExamplePeerContext ?? throw new ArgumentException("Expected ExamplePeerContext", nameof(peerContext));
            _messageWriter = PeerContext.GetMessageWriter();

            await OnPeerAttachedAsync().ConfigureAwait(false);
        }
Пример #5
0
        public T Get <T>(Guid serviceId, PeerContext peer)
        {
            var result = (T)servicesByTypeAndPeerId.GetOrAdd(
                Tuple.Create(typeof(T), peer.Identity.Id),
                add => CreateInvocationProxy <T>(serviceId, peer));

            return(result);
        }
Пример #6
0
        public T Get <T>(PeerContext peer)
        {
            Guid serviceId;

            if (!typeof(T).TryGetInterfaceGuid(out serviceId))
            {
                throw new InvalidOperationException($"Service of type {typeof(T).FullName} does not have default service id.");
            }
            return(Get <T>(serviceId, peer));
        }
Пример #7
0
        private T CreateInvocationProxy <T>(Guid serviceId, PeerContext peer)
        {
            var remoteServiceInfo = new RemoveServiceInfo {
                Peer        = peer,
                ServiceType = typeof(T),
                ServiceId   = serviceId
            };
            var interceptor = new RemoteServiceProxyInvocationInterceptor(remoteServiceInfo, remoteServiceInvoker);

            return((T)proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof(T), interceptor));
        }
Пример #8
0
        static void Main(string[] args)
        {
            ILoggerFactory  loggerFactory = new LoggerFactory().AddConsole();
            ILogger <VkBot> logger        = loggerFactory.CreateLogger <VkBot>();

            ExampleSettings settings = ExampleSettings.TryToLoad(logger);

            VkBot bot = new VkBot(settings.AccessToken, settings.GroupUrl, logger);

            var keyboard = new KeyboardBuilder().SetOneTime().AddButton("тык", "").AddButton("тыдыщ", "").Build();

            bot.TemplateManager.Register(new RegexToActionTemplate("тык", (sender, eventArgs) =>
            {
                PeerContext context = eventArgs.PeerContext;
                long peerId         = eventArgs.Message.PeerId.Value;

                if (!context.Vars.ContainsKey("тыки"))
                {
                    context.Vars["тыки"] = 0;
                }

                sender.Api.Messages.Send(new MessagesSendParams()
                {
                    Keyboard = keyboard,
                    PeerId   = peerId,
                    Message  = $"тык номер {context.Vars["тыки"]++}",
                    RandomId = Math.Abs(Environment.TickCount)
                });
            }
                                                                   ));


            bot.TemplateManager.Register(new RegexToActionTemplate("тыдыщ", (sender, eventArgs) =>
            {
                if (!eventArgs.PeerContext.GlobalVars.ContainsKey("тыдыщи"))
                {
                    eventArgs.PeerContext.GlobalVars["тыдыщи"] = 0;
                }

                sender.Api.Messages.Send(new MessagesSendParams()
                {
                    Keyboard = keyboard,
                    PeerId   = eventArgs.Message.PeerId,
                    Message  = $"глобальный, междиалоговый тыдыщ номер {eventArgs.PeerContext.GlobalVars["тыдыщи"]++}",
                    RandomId = Math.Abs(Environment.TickCount)
                });
            }));

            bot.Start();
            bot.Dispose();
        }
Пример #9
0
        public void OnPeriodicWorkException(IPeriodicWork failedWork, Exception ex, ref IPeriodicWorkExceptionHandler.Feedback feedback)
        {
            string?disconnectionReason = failedWork switch
            {
                IPeriodicWork work when work == _headerSyncLoop => "Peer header syncing loop had failures.",
                  _ => null
            };

            if (disconnectionReason != null)
            {
                feedback.ContinueExecution = false;
                PeerContext.Disconnect(disconnectionReason);
            }
        }
        public async ValueTask <bool> ProcessMessageAsync(HandshakeMessage noiseMessage, CancellationToken cancellation)
        {
            if (PeerContext.HandshakeComplete)
            {
                logger.LogDebug("Receiving version while already handshaked, disconnect.");
                throw new ProtocolViolationException("Peer already handshaked, disconnecting because of protocol violation.");
            }

            switch (_handshakeActNumber)
            {
            case 1: // ActOne responder
            {
                logger.LogDebug("Handshake ActOne received.");
                await SendMessageAsync(Handshake(noiseMessage.Payload), cancellation).ConfigureAwait(false);

                _handshakeActNumber += 2;   // jump to act3
                logger.LogDebug("Handshake ActTwo sent.");
                break;
            }

            case 2: // ActTwo both
            {
                logger.LogDebug("Handshake ActTwo received.");
                await SendMessageAsync(Handshake(noiseMessage.Payload), cancellation).ConfigureAwait(false);

                PeerContext.OnHandshakeCompleted();
                _handshakeActNumber++;
                logger.LogDebug("Handshake ActThree sent.");
                break;
            }

            case 3: // ActThree Responder
            {
                logger.LogDebug("Handshake ActThree received.");
                _ = Handshake(noiseMessage.Payload);
                _handshakeActNumber++;
                logger.LogDebug("Handshake Init sent.");
                PeerContext.OnHandshakeCompleted();
                await SendMessageAsync(CreateInitMessage(), cancellation).ConfigureAwait(false);

                PeerContext.OnInitMessageCompleted();
                break;
            }
            }

            // will prevent to handle noise messages to other Processors
            return(false);
        }
        public async ValueTask <bool> ProcessMessageAsync(InitMessage message, CancellationToken cancellation)
        {
            logger.LogDebug("Handshake Init received.");

            if (PeerContext.InitComplete)
            {
                return(true);
            }

            // validate init message

            PeerContext.OnInitMessageCompleted();

            await SendMessageAsync(CreateInitMessage(), cancellation).ConfigureAwait(false);

            return(true);// new ValueTask<bool>(true);
        }
Пример #12
0
        /// <summary>
        /// Check if the client is allowed to connect based on certain criteria.
        /// </summary>
        /// <returns>When criteria is met returns <c>true</c>, to allow connection.</returns>
        private ServerPeerConnectionGuardResult EnsurePeerCanConnect(TcpClient tcpClient)
        {
            if (this.serverPeerConnectionGuards == null)
            {
                return(ServerPeerConnectionGuardResult.Success);
            }

            IPeerContext peerContext = new PeerContext((IPEndPoint)tcpClient.Client.LocalEndPoint, (IPEndPoint)tcpClient.Client.RemoteEndPoint);

            return((
                       from guard in this.serverPeerConnectionGuards
                       let guardResult = guard.Check(peerContext)
                                         where guardResult.IsDenied
                                         select guardResult
                       )
                   .DefaultIfEmpty(ServerPeerConnectionGuardResult.Success)
                   .FirstOrDefault());
        }
Пример #13
0
        private void PeerConnected(PeerConnection peer)
        {
            Log.LogInformation($"Connected to peer at {peer.Address}");

            lock (peersLock)
                peers.Add(peer);

            foreach (var module in modules.Modules)
            {
                var context = new PeerContext(
                    peer,
                    peer.GetCustomValues(module),
                    this,
                    messageId => RegisterModuleForMessageId(peer, module, messageId));
                module.OnPeerConnected(context);
            }

            peer.ReceiveData();
        }
Пример #14
0
 private void CheckSyncStallingLocked(BlockHeader bestHeader)
 {
     // Check for headers sync timeouts
     if (_status.IsSynchronizingHeaders && _status.HeadersSyncTimeout < long.MaxValue)
     {
         long now = _dateTimeProvider.GetTimeMicros();
         // Detect whether this is a stalling initial-headers-sync peer
         if (bestHeader.TimeStamp <= _dateTimeProvider.GetAdjustedTimeAsUnixTimestamp() - 24 * 60 * 60)
         {
             bool isTheOnlyPeerSynching = true; //nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)
             if (now > _status.HeadersSyncTimeout && isTheOnlyPeerSynching)
             {
                 // Disconnect a (non-whitelisted) peer if it is our only sync peer,
                 // and we have others we could be using instead.
                 // Note: If all our peers are inbound, then we won't
                 // disconnect our sync peer for stalling; we have bigger
                 // problems if we can't get any outbound peers.
                 if (!PeerContext.Permissions.Has(BitcoinPeerPermissions.NOBAN))
                 {
                     PeerContext.Disconnect("Timeout downloading headers, disconnecting");
                     return;
                 }
                 else
                 {
                     logger.LogDebug("Timeout downloading headers from whitelisted peer {PeerId}, not disconnecting.", PeerContext.PeerId);
                     // Reset the headers sync state so that we have a
                     // chance to try downloading from a different peer.
                     // Note: this will also result in at least one more
                     // getheaders message to be sent to
                     // this peer (eventually).
                     _status.IsSynchronizingHeaders = false;
                     _status.HeadersSyncTimeout     = 0;
                 }
             }
         }
         else
         {
             // After we've caught up once, reset the timeout so we can't trigger disconnect later.
             _status.HeadersSyncTimeout = long.MaxValue;
         }
     }
 }
        public async Task DispatchAsync(MessageDto message)
        {
            await TaskEx.YieldToThreadPool();

            bool a = identity.Matches(message.SenderId, IdentityMatchingScope.LocalIdentity);
            bool b = !identity.Matches(message.ReceiverId, IdentityMatchingScope.Broadcast);

            if (a || b)
            {
                return;
            }

            PeerContext peerContext = null;

            if (message.SenderId != Guid.Empty)
            {
                peerContext = peerTable.GetOrAdd(message.SenderId);
                await peerContext.WaitForDiscoveryAsync().ConfigureAwait(false);
            }

            await RouteAsyncVisitor.Visit(inboundMessageRouter, message, peerContext).ConfigureAwait(false);
        }
Пример #16
0
        private void ProcessLongPollEvents(BotsLongPollHistoryResponse pollResponse)
        {
            foreach (GroupUpdate update in pollResponse.Updates)
            {
                OnGroupUpdateReceived?.Invoke(this, new GroupUpdateReceivedEventArgs(update,
                                                                                     this.PeerContextManager.GlobalVars));
                if (update.Type == GroupUpdateType.MessageNew)
                {
                    long        peerId      = update.Message.PeerId.Value;
                    PeerContext peerContext = null;

                    if (!this.PeerContextManager.Peers.TryGetValue(peerId, out peerContext))
                    {
                        peerContext = new PeerContext(this.PeerContextManager.GlobalVars);
                        this.PeerContextManager.Peers.Add(peerId, peerContext);
                    }

                    OnMessageReceived?.Invoke(this, new MessageReceivedEventArgs(update.Message, peerContext));
                    this.SearchTemplatesMatchingMessageAndHandle(update.Message, peerContext);
                }
            }
        }
Пример #17
0
        /// <summary>
        /// Check if the client is allowed to connect based on certain criteria.
        /// </summary>
        /// <returns>When criteria is met returns <c>true</c>, to allow connection.</returns>
        private void EnsurePeerCanConnect(ConnectionContext connection)
        {
            if (this.serverPeerConnectionGuards == null)
            {
                return;
            }

            IPeerContext peerContext = new PeerContext((IPEndPoint)connection.LocalEndPoint, (IPEndPoint)connection.RemoteEndPoint);

            ServerPeerConnectionGuardResult result = (
                from guard in this.serverPeerConnectionGuards
                let guardResult = guard.Check(peerContext)
                                  where guardResult.IsDenied
                                  select guardResult
                )
                                                     .DefaultIfEmpty(ServerPeerConnectionGuardResult.Success)
                                                     .FirstOrDefault();

            if (result.IsDenied)
            {
                this.logger.LogDebug("Connection from client '{ConnectingPeerEndPoint}' was rejected because of {ClientDisconnectedReason} and will be closed.", connection.RemoteEndPoint, result.DenyReason);
                connection.Abort(new ConnectionAbortedException(result.DenyReason));
            }
        }
        private void PeerConnected(IPeer e)
        {
            if (!(e is BitTorrentPeer peer))
            {
                throw new ArgumentException($"Expected peer of type {typeof(BitTorrentPeer)} but was {typeof(IPeer)}");
            }

            _logger.LogInformation($"Connected to peer at {peer.Address}");

            lock (_peersLock)
                _peers.Add(peer);

            foreach (var module in _modules)
            {
                var context = new PeerContext(
                    peer,
                    peer.GetCustomValues(module),
                    this,
                    messageId => RegisterModuleForMessageId(peer, module, messageId));
                module.OnPeerConnected(context);
            }

            peer.ReceiveData();
        }
Пример #19
0
 public KcpCodec(PeerContext x)
 {
     this.x = x;
     CreateKcp(x);
 }
Пример #20
0
 public ExPeer(PeerContext pc) : base(pc)
 {
     Console.WriteLine($"{nameof(ExPeer)} sid:{pc.SessionId} created");
 }
Пример #21
0
 public TestUdpPeer2(PeerContext pc) : base(pc)
 {
     Console.WriteLine($"{nameof(TestUdpPeer2)} sid:{pc.SessionId} created");
 }
Пример #22
0
 public BigBuffPeerFlush(PeerContext pc) : base(pc)
 {
     Console.WriteLine($"{nameof(BigBuffPeerFlush)} sid:{pc.SessionId} created");
 }
Пример #23
0
        async Task CreateOrDeletePeerConnectionAsync(Guid peerId, string peerName, bool isInitiator, bool isDelete = false)
        {
            try
            {
                PeerContext        peerContext    = null;
                IRTCPeerConnection peerConnection = null;
                IMediaStream       mediaStream    = null;
                IRTCDataChannel    dataChannel    = null;

                if (isDelete)
                {
                    peerContext    = _connectionContext.PeerContexts.Single(context => context.Id.Equals(peerId));
                    peerConnection = peerContext.PeerConnection;

                    peerConnection.OnConnectionStateChanged   -= OnConnectionStateChanged;
                    peerConnection.OnDataChannel              -= OnDataChannel;
                    peerConnection.OnIceCandidate             -= OnIceCandidate;
                    peerConnection.OnIceConnectionStateChange -= OnIceConnectionStateChange;
                    peerConnection.OnIceGatheringStateChange  -= OnIceGatheringStateChange;
                    peerConnection.OnNegotiationNeeded        -= OnNegotiationNeeded;
                    peerConnection.OnSignallingStateChange    -= OnSignallingStateChange;
                    peerConnection.OnTrack -= OnTrack;

                    // Remove local tracks and close.
                    var senders = peerConnection.GetSenders();
                    foreach (var sender in senders)
                    {
                        peerConnection.RemoveTrack(sender);
                    }
                    peerConnection.Close();

                    _connectionContext.PeerContexts.Remove(peerContext);
                }
                else
                {
                    mediaStream = _webRtc.Window(_jsRuntime).MediaStream();
                    RTCIceServer[] iceServers = _connectionContext.IceServers;
                    if (iceServers is null)
                    {
                        var result = await _signalingServerApi.GetIceServersAsync();

                        if (!result.IsOk)
                        {
                            throw new Exception($"{result.ErrorMessage}");
                        }
                        iceServers = result.Value;
                        _connectionContext.IceServers = iceServers;
                    }
                    var configuration = new RTCConfiguration
                    {
                        IceServers = iceServers,
                        //PeerIdentity = peerName
                    };

                    _logger.LogInformation($"################ LIST OF ICE SERVERS ################");
                    foreach (var iceServer in configuration.IceServers)
                    {
                        foreach (var url in iceServer.Urls)
                        {
                            _logger.LogInformation($"\t - {url}");
                        }
                    }
                    _logger.LogInformation($"#####################################################");

                    peerConnection = _webRtc.Window(_jsRuntime).RTCPeerConnection(configuration);
                    peerContext    = new PeerContext
                    {
                        Id             = peerId,
                        Name           = peerName,
                        PeerConnection = peerConnection,
                        IsInitiator    = isInitiator,
                    };
                    _connectionContext.PeerContexts.Add(peerContext);

                    peerConnection.OnConnectionStateChanged   += OnConnectionStateChanged;
                    peerConnection.OnDataChannel              += OnDataChannel;
                    peerConnection.OnIceCandidate             += OnIceCandidate;
                    peerConnection.OnIceConnectionStateChange += OnIceConnectionStateChange;
                    peerConnection.OnIceGatheringStateChange  += OnIceGatheringStateChange;
                    peerConnection.OnNegotiationNeeded        += OnNegotiationNeeded;
                    peerConnection.OnSignallingStateChange    += OnSignallingStateChange;
                    peerConnection.OnTrack += OnTrack;


                    if (_connectionContext.UserContext.DataChannelName is not null && isInitiator)
                    {
                        dataChannel = peerConnection.CreateDataChannel(
                            _connectionContext.UserContext.DataChannelName,
                            new RTCDataChannelInit
                        {
                            Negotiated = false,
                        });
                    }

                    if (_connectionContext.UserContext.LocalStream is not null)
                    {
                        var videoTrack = _connectionContext.UserContext.LocalStream.GetVideoTracks().FirstOrDefault();
                        var audioTrack = _connectionContext.UserContext.LocalStream.GetAudioTracks().FirstOrDefault();
                        if (videoTrack is not null)
                        {
                            peerConnection.AddTrack(videoTrack, _connectionContext.UserContext.LocalStream);
                        }
                        if (audioTrack is not null)
                        {
                            peerConnection.AddTrack(audioTrack, _connectionContext.UserContext.LocalStream);
                        }
                    }
                }

                void OnConnectionStateChanged(object s, EventArgs e)
                {
                    _logger.LogInformation(
                        $"######## OnConnectionStateChanged - room:{_connectionContext.UserContext.Room} " +
                        $"user:{_connectionContext.UserContext.Name} " +
                        $"peerUser:{peerName} " +
                        $"connectionState:{peerConnection.ConnectionState}");
                    if (peerConnection.ConnectionState == RTCPeerConnectionState.Connected)
                    {
                        _connectionContext.Observer.OnNext(new PeerResponse
                        {
                            Type        = PeerResponseType.PeerJoined,
                            Id          = peerId,
                            Name        = peerName,
                            MediaStream = mediaStream,
                            DataChannel = isInitiator ? dataChannel : null
                        });
                    }
                    //// WILL BE HANDLED BY PEER LEFT
                    //else if (peerConnection.ConnectionState == RTCPeerConnectionState.Disconnected)
                    //ConnectionResponseSubject.OnCompleted();
                }
                void OnDataChannel(object s, IRTCDataChannelEvent e)
                {
                    _logger.LogInformation(
                        $"######## OnDataChannel - room:{_connectionContext.UserContext.Room} " +
                        $"user:{_connectionContext.UserContext.Name} " +
                        $"peerUser:{peerName} " +
                        $"state:{e.Channel.ReadyState}");

                    dataChannel?.Close();
                    dataChannel?.Dispose();

                    dataChannel = e.Channel;
                    _connectionContext.Observer.OnNext(new PeerResponse
                    {
                        Type        = PeerResponseType.PeerJoined,
                        Name        = peerName,
                        MediaStream = null,
                        DataChannel = dataChannel
                    });
                }
                async void OnIceCandidate(object s, IRTCPeerConnectionIceEvent e)
                {
                    //_logger.LogInformation(
                    //    $"######## OnIceCandidate - room:{roomName} " +
                    //    $"user:{connectionContext.ConnectionRequestParameters.ConnectionParameters.UserName} " +
                    //    $"peerUser:{peerName}");

                    // 'null' is valid and indicates end of ICE gathering process.
                    if (e.Candidate is not null)
                    {
                        var iceCandidate = new RTCIceCandidateInit
                        {
                            Candidate     = e.Candidate.Candidate,
                            SdpMid        = e.Candidate.SdpMid,
                            SdpMLineIndex = e.Candidate.SdpMLineIndex,
                            //UsernameFragment = ???
                        };
                        var ice = JsonSerializer.Serialize(iceCandidate, JsonHelper.WebRtcJsonSerializerOptions);
                        _logger.LogInformation(
                            $"--------> Sending ICE Candidate - room:{_connectionContext.UserContext.Room} " +
                            $"user:{_connectionContext.UserContext.Name} " +
                            $"peerUser:{peerName} " +
                            $"ice:{ice}");
                        var result = await _signalingServerApi.IceAsync(peerId, ice);

                        if (!result.IsOk)
                        {
                            throw new Exception($"{result.ErrorMessage}");
                        }
                    }
                }
                void OnIceConnectionStateChange(object s, EventArgs e)
                {
                    _logger.LogInformation(
                        $"######## OnIceConnectionStateChange - room:{_connectionContext.UserContext.Room} " +
                        $"user:{_connectionContext.UserContext.Name} " +
                        $"peerUser:{peerName} " +
                        $"iceConnectionState:{peerConnection.IceConnectionState}");
                }
                void OnIceGatheringStateChange(object s, EventArgs e)
                {
                    _logger.LogInformation(
                        $"######## OnIceGatheringStateChange - room:{_connectionContext.UserContext.Room} " +
                        $"user:{_connectionContext.UserContext.Name} " +
                        $"peerUser:{peerName} " +
                        $"iceGatheringState: {peerConnection.IceGatheringState}");
                }
                void OnNegotiationNeeded(object s, EventArgs e)
                {
                    _logger.LogInformation(
                        $"######## OnNegotiationNeeded - room:{_connectionContext.UserContext.Room} " +
                        $"user:{_connectionContext.UserContext.Name} " +
                        $"peerUser:{peerName}");
                    // TODO: WHAT IF Not initiator adds track (which trigggers this event)???
                }
                void OnSignallingStateChange(object s, EventArgs e)
                {
                    _logger.LogInformation(
                        $"######## OnSignallingStateChange - room:{_connectionContext.UserContext.Room} " +
                        $"user:{_connectionContext.UserContext.Name} " +
                        $"peerUser:{peerName}, " +
                        $"signallingState:{ peerConnection.SignalingState }");
                    //RoomEventSubject.OnNext(new RoomEvent
                    //{
                    //    Code = RoomEventCode.PeerJoined,
                    //    RoomName = roomName,
                    //    PeerUserName = peerName,
                    //    MediaStream = mediaStream
                    //});
                }
                void OnTrack(object s, IRTCTrackEvent e)
                {
                    _logger.LogInformation(
                        $"######## OnTrack - room:{_connectionContext.UserContext.Room} " +
                        $"user:{_connectionContext.UserContext.Name} " +
                        $"peerUser:{peerName} " +
                        $"trackType:{e.Track.Kind}");
                    mediaStream.AddTrack(e.Track);
                }
            }
            catch (Exception ex)
            {
                _connectionContext?.Observer.OnNext(new PeerResponse
                {
                    Type         = PeerResponseType.PeerError,
                    Id           = peerId,
                    Name         = peerName,
                    ErrorMessage = ex.Message
                });
            }
        }
 public static Task Visit(InboundMessageRouter router, MessageDto message, PeerContext peer)
 {
     return(visitorFactory.Get(message.Body.GetType())(router, message, peer));
 }
                public static async Task Visit(InboundMessageRouter router, MessageDto message, PeerContext peer)
                {
                    var e = eventPool.TakeObject();

                    e.Message = message;
                    e.Sender  = peer;

                    if (!await router.TryRouteAsync(e).ConfigureAwait(false))
                    {
                        logger.Trace($"Failed to route inbound message of body type {e.Body?.GetType().Name ?? "[null]"}");
                    }

                    e.Message = null;
                    eventPool.ReturnObject(e);
                }