private void DoReceive(ChannelRegistration registration, IActorRef handler)
        {
            Action <int, ByteBuffer> innerReceive = null;

            innerReceive = (readsLeft, buffer) =>
            {
                buffer.Clear();
                buffer.Limit(_udp.Setting.DirectBufferSize);

                var sender = Channel.Receive(buffer);
                if (sender != null)
                {
                    buffer.Flip();
                    handler.Tell(new Udp.Received(ByteString.Create(buffer), sender));
                    if (readsLeft > 0)
                    {
                        innerReceive(readsLeft - 1, buffer);
                    }
                }
            };

            var buffr = _udp.BufferPool.Acquire();

            try
            {
                innerReceive(_udp.Setting.BatchReceiveLimit, buffr);
            }
            finally
            {
                _udp.BufferPool.Release(buffr);
                registration.EnableInterest(SocketAsyncOperation.Receive);
            }
        }
Beispiel #2
0
        private void DoRead(ChannelRegistration registration, IActorRef handler)
        {
            Action <int, ByteBuffer> innerRead = null;

            innerRead = (readsLeft, buffer) =>
            {
                buffer.Clear();
                buffer.Limit(_udpConn.Settings.DirectBufferSize);
                if (_channel.Read(buffer) > 0)
                {
                    buffer.Flip();
                    handler.Tell(new UdpConnected.Received(ByteString.Create(buffer)));
                    innerRead(readsLeft - 1, buffer);
                }
            };
            var buffr = _udpConn.BufferPool.Acquire();

            try
            {
                innerRead(_udpConn.Settings.BatchReceiveLimit, buffr);
            }
            finally
            {
                registration.EnableInterest(SocketAsyncOperation.Receive);
                _udpConn.BufferPool.Release(buffr);
            }
        }
Beispiel #3
0
 private void Register(EndPoint address, ChannelRegistration registration)
 {
     ReportConnectFailure(() =>
     {
         Log.Debug("Attempting connection to [{0}]", address);
         if (Channel.Connect(address))
         {
             CompleteConnect(registration, _commander, _connect.Options);
         }
         else
         {
             registration.EnableInterest(SocketAsyncOperation.Connect);
             Become(Connecting(registration, Tcp.Settings.FinishConnectRetries));
         }
     });
 }
Beispiel #4
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);
            }
        }
        private Receive ReadHandlers(ChannelRegistration registration)
        {
            return(message =>
            {
                if (message is Udp.SuspendReading)
                {
                    registration.DisableInterest(SocketAsyncOperation.Receive);
                    return true;
                }
                if (message is Udp.ResumeReading)
                {
                    registration.EnableInterest(SocketAsyncOperation.Receive);
                    return true;
                }
                if (message is SelectionHandler.ChannelReadable)
                {
                    DoReceive(registration, _bind.Handler);
                    return true;
                }

                if (message is Udp.Unbind)
                {
                    _log.Debug("Unbinding endpoint [{0}]", _bind.LocalAddress);
                    try
                    {
                        Channel.Close();
                        Sender.Tell(IO.Udp.Unbound.Instance);
                        _log.Debug("Unbound endpoint [{0}], stopping listener", _bind.LocalAddress);
                    }
                    finally
                    {
                        Context.Stop(Self);
                    }
                    return true;
                }
                return false;
            });
        }
Beispiel #6
0
        private Receive Connected(ChannelRegistration registration)
        {
            return(message =>
            {
                if (message is UdpConnected.SuspendReading)
                {
                    registration.DisableInterest(SocketAsyncOperation.Receive);
                    return true;
                }
                if (message is UdpConnected.ResumeReading)
                {
                    registration.EnableInterest(SocketAsyncOperation.Receive);
                    return true;
                }
                if (message is SelectionHandler.ChannelReadable)
                {
                    DoRead(registration, _connect.Handler);
                    return true;
                }

                if (message is UdpConnected.Disconnect)
                {
                    _log.Debug("Closing UDP connection to [{0}]", _connect.RemoteAddress);
                    _channel.Close();
                    Sender.Tell(UdpConnected.Disconnected.Instance);
                    _log.Debug("Connection closed to [{0}], stopping listener", _connect.RemoteAddress);
                    Context.Stop(Self);
                    return true;
                }

                var send = message as UdpConnected.Send;
                if (send != null && WritePending)
                {
                    if (_udpConn.Settings.TraceLogging)
                    {
                        _log.Debug("Dropping write because queue is full");
                    }
                    Sender.Tell(new UdpConnected.CommandFailed(send));
                    return true;
                }
                if (send != null && send.Payload.IsEmpty)
                {
                    if (send.WantsAck)
                    {
                        Sender.Tell(send.Ack);
                    }
                    return true;
                }
                if (send != null)
                {
                    _pendingSend = Tuple.Create(send, Sender);
                    registration.EnableInterest(SocketAsyncOperation.Send);
                    return true;
                }
                if (message is SelectionHandler.ChannelWritable)
                {
                    DoWrite();
                    return true;
                }
                return false;
            });
        }