예제 #1
0
        /// <summary>
        /// TBD
        /// </summary>
        public UdpConnection(UdpConnectedExt udp, IActorRef commander, Connect connect)
        {
            Udp        = udp;
            _commander = commander;
            _connect   = connect;

            Context.Watch(connect.Handler);

            if (connect.RemoteAddress is DnsEndPoint remoteAddress)
            {
                var resolved = Dns.ResolveName(remoteAddress.Host, Context.System, Self);
                if (resolved != null)
                {
                    DoConnect(new IPEndPoint(resolved.Addr, remoteAddress.Port));
                }
                else
                {
                    Context.Become(Resolving(remoteAddress));
                }
            }
            else
            {
                DoConnect(_connect.RemoteAddress);
            }
        }
예제 #2
0
        protected override bool Receive(object message)
        {
            var registration = message as ChannelRegistration;

            if (registration != null)
            {
                ReportConnectFailure(() =>
                {
                    var remoteAddress = _connect.RemoteAddress as DnsEndPoint;
                    if (remoteAddress != null)
                    {
                        Log.Debug("Resolving {0} before connecting", remoteAddress.Host);
                        var resolved = Dns.ResolveName(remoteAddress.Host, Context.System, Self);
                        if (resolved == null)
                        {
                            Become(Resolving(remoteAddress, registration));
                        }
                        else
                        {
                            Register(new IPEndPoint(resolved.Addr, remoteAddress.Port), registration);
                        }
                    }
                    else
                    {
                        Register(_connect.RemoteAddress, registration);
                    }
                });
                return(true);
            }
            return(false);
        }
예제 #3
0
 protected override void PreStart()
 {
     ReportConnectFailure(() =>
     {
         if (_connect.RemoteAddress is DnsEndPoint)
         {
             var remoteAddress = (DnsEndPoint)_connect.RemoteAddress;
             Log.Debug("Resolving {0} before connecting", remoteAddress.Host);
             var resolved = Dns.ResolveName(remoteAddress.Host, Context.System, Self);
             if (resolved == null)
             {
                 Become(Resolving(remoteAddress));
             }
             else if (resolved.Ipv4.Any() && resolved.Ipv6.Any()) // one of both families
             {
                 Register(new IPEndPoint(resolved.Ipv4.FirstOrDefault(), remoteAddress.Port), new IPEndPoint(resolved.Ipv6.FirstOrDefault(), remoteAddress.Port));
             }
             else // one or the other
             {
                 Register(new IPEndPoint(resolved.Addr, remoteAddress.Port), null);
             }
         }
         else if (_connect.RemoteAddress is IPEndPoint)
         {
             Register((IPEndPoint)_connect.RemoteAddress, null);
         }
         else
         {
             throw new NotSupportedException($"Couldn't connect to [{_connect.RemoteAddress}]: only IP and DNS-based endpoints are supported");
         }
     });
 }
예제 #4
0
        public UdpConnection(UdpConnectedExt udpConn,
                             IChannelRegistry channelRegistry,
                             IActorRef commander,
                             UdpConnected.Connect connect)
        {
            _udpConn         = udpConn;
            _channelRegistry = channelRegistry;
            _commander       = commander;
            _connect         = connect;

            Context.Watch(connect.Handler);

            var remoteAddress = connect.RemoteAddress as DnsEndPoint;

            if (remoteAddress != null)
            {
                var resolved = Dns.ResolveName(remoteAddress.Host, Context.System, Self);
                if (resolved != null)
                {
                    DoConnect(new IPEndPoint(resolved.Addr, remoteAddress.Port));
                }
                else
                {
                    Context.Become(Resolving(remoteAddress));
                }
            }
            else
            {
                DoConnect(_connect.RemoteAddress);
            }
        }
예제 #5
0
        public Receive SendHandlers(ChannelRegistration registration)
        {
            return(message =>
            {
                var send = message as Udp.Send;
                if (send != null && HasWritePending)
                {
                    if (Udp.Setting.TraceLogging)
                    {
                        _log.Debug("Dropping write because queue is full");
                    }
                    Sender.Tell(new Udp.CommandFailed(send));
                    return true;
                }
                if (send != null && send.Payload.IsEmpty)
                {
                    if (send.WantsAck)
                    {
                        Sender.Tell(send.Ack);
                    }
                    return true;
                }
                if (send != null)
                {
                    _pendingSend = send;
                    _pendingCommander = Sender;

                    var dns = send.Target as DnsEndPoint;
                    if (dns != null)
                    {
                        var resolved = Dns.ResolveName(dns.Host, Context.System, Self);
                        if (resolved != null)
                        {
                            try
                            {
                                _pendingSend = new Udp.Send(_pendingSend.Payload, new IPEndPoint(resolved.Addr, dns.Port), _pendingSend.Ack);
                                DoSend(registration);
                            }
                            catch (Exception ex)
                            {
                                Sender.Tell(new Udp.CommandFailed(send));
                                _log.Debug("Failure while sending UDP datagram to remote address [{0}]: {1}", send.Target, ex);
                                _retriedSend = false;
                                _pendingSend = null;
                                _pendingCommander = null;
                            }
                        }
                    }
                    else
                    {
                        DoSend(registration);
                    }
                    return true;
                }
                if (message is SelectionHandler.ChannelWritable && HasWritePending)
                {
                    DoSend(registration);
                    return true;
                }
                return false;
            });
        }
예제 #6
0
        public bool SendHandlers(object message)
        {
            switch (message)
            {
            case Send send when HasWritePending:
            {
                if (Udp.Setting.TraceLogging)
                {
                    _log.Debug("Dropping write because queue is full");
                }
                Sender.Tell(new CommandFailed(send));
                return(true);
            }

            case Send send:
            {
                if (send.HasData)
                {
                    _pendingSend      = send;
                    _pendingCommander = Sender;

                    //var e = Udp.SocketEventArgsPool.Acquire(Self);
                    if (send.Target is DnsEndPoint dns)
                    {
                        var resolved = Dns.ResolveName(dns.Host, Context.System, Self);
                        if (resolved != null)
                        {
                            try
                            {
                                _pendingSend = new Send(_pendingSend.Payload, new IPEndPoint(resolved.Addr, dns.Port), _pendingSend.Ack);
                                DoSend();
                            }
                            catch (Exception ex)
                            {
                                Sender.Tell(new CommandFailed(send));
                                _log.Debug("Failure while sending UDP datagram to remote address [{0}]: {1}",
                                           send.Target, ex);
                                _retriedSend      = false;
                                _pendingSend      = null;
                                _pendingCommander = null;
                            }
                        }
                    }
                    else
                    {
                        DoSend();
                    }
                }
                else
                {
                    if (send.WantsAck)
                    {
                        Sender.Tell(send.Ack);
                    }
                }

                return(true);
            }

            case SocketSent sent:
            {
                if (sent.EventArgs.SocketError == SocketError.Success)
                {
                    if (Udp.Setting.TraceLogging)
                    {
                        _log.Debug("Wrote [{0}] bytes to channel", sent.EventArgs.BytesTransferred);
                    }

                    if (_pendingSend.WantsAck)
                    {
                        _pendingCommander.Tell(_pendingSend.Ack);
                    }

                    _retriedSend      = false;
                    _pendingSend      = null;
                    _pendingCommander = null;
                }
                else if (_retriedSend)
                {
                    _pendingCommander.Tell(new CommandFailed(_pendingSend));

                    _retriedSend      = false;
                    _pendingSend      = null;
                    _pendingCommander = null;
                }
                else
                {
                    DoSend();
                    _retriedSend = true;
                }
                return(true);
            }

            default: return(false);
            }
        }