예제 #1
0
 /** connection is closing but a write has to be finished first */
 private Receive ClosingWithPendingWrite(ConnectionInfo info, IActorRef closeCommandor,
                                         Tcp.ConnectionClosed closedEvent)
 {
     return(message =>
     {
         if (message is Tcp.SuspendReading)
         {
             SuspendReading(info);
             return true;
         }
         if (message is Tcp.ResumeReading)
         {
             ResumeReading(info);
             return true;
         }
         if (message is SelectionHandler.ChannelReadable)
         {
             DoRead(info, closeCommandor);
             return true;
         }
         if (message is SelectionHandler.ChannelWritable)
         {
             DoWrite(info);
             if (!WritePending())    // writing is now finished
             {
                 HandleClose(info, closeCommandor, closedEvent);
             }
             return true;
         }
         var updatePendingWrite = message as UpdatePendingWriteAndThen;
         if (updatePendingWrite != null)
         {
             _pendingWrite = updatePendingWrite.RemainingWrite;
             updatePendingWrite.Work();
             if (WritePending())
             {
                 info.Registration.EnableInterest(SocketAsyncOperation.Send);
             }
             else
             {
                 HandleClose(info, closeCommandor, closedEvent);
             }
             return true;
         }
         var writeFailed = message as WriteFileFailed;
         if (writeFailed != null)
         {
             HandleError(info.Handler, writeFailed.E);  // rethrow exception from dispatcher task
             return true;
         }
         if (message is Tcp.Abort)
         {
             HandleClose(info, Sender, IO.Tcp.Aborted.Instance);
             return true;
         }
         return false;
     });
 }
예제 #2
0
        private void HandleClose(ConnectionInfo info, IActorRef closeCommander, Tcp.ConnectionClosed closedEvent)
        {
            if (closedEvent is Tcp.Aborted)
            {
                if (_tcp.Settings.TraceLogging)
                {
                    _log.Debug("Got Abort command. RESETing connection.");
                }
                DoCloseConnection(info.Handler, closeCommander, closedEvent);
                return;
            }
            if (closedEvent is Tcp.PeerClosed && info.KeepOpenOnPeerClosed)
            {
                // report that peer closed the connection
                info.Handler.Tell(IO.Tcp.PeerClosed.Instance);
                // used to check if peer already closed its side later
                _peerClosed = true;
                Context.Become(PeerSentEOF(info));
                return;
            }
            if (WritePending())   // finish writing first
            {
                if (_tcp.Settings.TraceLogging)
                {
                    _log.Debug("Got Close command but write is still pending.");
                }
                Context.Become(ClosingWithPendingWrite(info, closeCommander, closedEvent));
                return;
            }
            if (closedEvent is Tcp.ConfirmedClosed) // shutdown output and wait for confirmation
            {
                if (_tcp.Settings.TraceLogging)
                {
                    _log.Debug("Got ConfirmedClose command, sending FIN.");
                }

                // If peer closed first, the socket is now fully closed.
                // Also, if shutdownOutput threw an exception we expect this to be an indication
                // that the peer closed first or concurrently with this code running.
                if (_peerClosed || !SafeShutdownOutput())
                {
                    DoCloseConnection(info.Handler, closeCommander, closedEvent);
                }
                else
                {
                    Context.Become(Closing(info, closeCommander));
                }
                return;
            }
            // close now
            if (_tcp.Settings.TraceLogging)
            {
                _log.Debug("Got Close command, closing connection.");
            }
            DoCloseConnection(info.Handler, closeCommander, closedEvent);
        }
예제 #3
0
 private void DoCloseConnection(IActorRef handler, IActorRef closeCommander, Tcp.ConnectionClosed closedEvent)
 {
     if (closedEvent is Tcp.Aborted)
     {
         Abort();
     }
     else
     {
         _channel.Close();
     }
     StopWith(new CloseInformation(new HashSet <IActorRef>(new[] { handler, closeCommander }.Where(x => x != null)), closedEvent));
 }