Exemplo n.º 1
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;
            };
        }
Exemplo n.º 2
0
        private void DoSend(ChannelRegistration registration)
        {
            var buffer = Udp.BufferPool.Acquire();
            try
            {
                buffer.Clear();
                _pendingSend.Payload.CopyToBuffer(buffer);
                buffer.Flip();
                var writtenBytes = Channel.Send(buffer, _pendingSend.Target);
                if (Udp.Setting.TraceLogging) _log.Debug("Wrote [{0}] bytes to channel", writtenBytes);

                // Datagram channel either sends the whole message, or nothing
                if (writtenBytes == 0)
                {
                    if (_retriedSend)
                    {
                        _pendingCommander.Tell(new Udp.CommandFailed(_pendingSend));
                        _retriedSend = false;
                        _pendingSend = null;
                        _pendingCommander = null;
                    }
                    else
                    {
                        registration.EnableInterest(SocketAsyncOperation.Send);
                        _retriedSend = true;
                    }
                }
                else
                {
                    if (_pendingSend.WantsAck) _pendingCommander.Tell(_pendingSend.Ack);
                    _retriedSend = false;
                    _pendingSend = null;
                    _pendingCommander = null;
                }
            }
            finally
            {
                Udp.BufferPool.Release(buffer);
            }
        }