Updated the Endpoint interface to define a close() method

that can optionally flush the queued messages.  Modified
DefaultServer to close-with-flush when kicking a client
so that the disconnect message actually gets to them.


git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7049 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
PSp..om 14 years ago
parent 0d23903830
commit b46a09066d
  1. 8
      engine/src/networking/com/jme3/network/base/DefaultServer.java
  2. 11
      engine/src/networking/com/jme3/network/kernel/Endpoint.java
  3. 26
      engine/src/networking/com/jme3/network/kernel/tcp/NioEndpoint.java
  4. 8
      engine/src/networking/com/jme3/network/kernel/tcp/SelectorKernel.java
  5. 9
      engine/src/networking/com/jme3/network/kernel/udp/UdpEndpoint.java

@ -409,14 +409,12 @@ public class DefaultServer implements Server
m.setReliable( true ); m.setReliable( true );
send( m ); send( m );
// Note: without a way to flush the pending messages
// during close, the above message may never
// go out.
// Just close the reliable endpoint // Just close the reliable endpoint
// fast will be cleaned up as a side-effect // fast will be cleaned up as a side-effect
if( reliable != null ) { if( reliable != null ) {
reliable.close(); // Close with flush so we make sure our
// message gets out
reliable.close(true);
} }
} }

@ -73,7 +73,16 @@ public interface Endpoint
public void send( ByteBuffer data ); public void send( ByteBuffer data );
/** /**
* Closes this endpoint. * Closes this endpoint without flushing any of its
* currently enqueued outbound data.
*/ */
public void close(); public void close();
/**
* Closes this endpoint, optionally flushing any queued
* data before closing. As soon as this method is called,
* ne send() calls will fail with an exception... even while
* close() is still flushing the earlier queued messages.
*/
public void close(boolean flushData);
} }

@ -50,10 +50,13 @@ import com.jme3.network.kernel.*;
*/ */
public class NioEndpoint implements Endpoint public class NioEndpoint implements Endpoint
{ {
protected static final ByteBuffer CLOSE_MARKER = ByteBuffer.allocate(0);
private long id; private long id;
private SocketChannel socket; private SocketChannel socket;
private SelectorKernel kernel; private SelectorKernel kernel;
private ConcurrentLinkedQueue<ByteBuffer> outbound = new ConcurrentLinkedQueue<ByteBuffer>(); private ConcurrentLinkedQueue<ByteBuffer> outbound = new ConcurrentLinkedQueue<ByteBuffer>();
private boolean closing = false;
public NioEndpoint( SelectorKernel kernel, long id, SocketChannel socket ) public NioEndpoint( SelectorKernel kernel, long id, SocketChannel socket )
{ {
@ -69,6 +72,21 @@ public class NioEndpoint implements Endpoint
public void close() public void close()
{ {
close(false);
}
public void close( boolean flushData )
{
if( flushData ) {
closing = true;
// Enqueue a close marker message to let the server
// know we should close
send( CLOSE_MARKER, false, true );
return;
}
try { try {
kernel.closeEndpoint(this); kernel.closeEndpoint(this);
} catch( IOException e ) { } catch( IOException e ) {
@ -142,7 +160,13 @@ public class NioEndpoint implements Endpoint
} }
public void send( ByteBuffer data ) public void send( ByteBuffer data )
{ {
if( data == null ) {
throw new IllegalArgumentException( "Data cannot be null." );
}
if( closing ) {
throw new KernelException( "Endpoint has been closed:" + socket );
}
send( data, true, true ); send( data, true, true );
} }

@ -354,6 +354,14 @@ public class SelectorKernel extends AbstractKernel
// We will send what we can and move on. // We will send what we can and move on.
ByteBuffer current = p.peekPending(); ByteBuffer current = p.peekPending();
if( current == NioEndpoint.CLOSE_MARKER ) {
// This connection wants to be closed now
closeEndpoint(p);
// Nothing more to do
return;
}
c.write( current ); c.write( current );
// If we wrote all of that packet then we need to remove it // If we wrote all of that packet then we need to remove it

@ -74,6 +74,15 @@ public class UdpEndpoint implements Endpoint
public void close() public void close()
{ {
close( false );
}
public void close( boolean flush )
{
// No real reason to flush UDP traffic yet... especially
// when considering that the outbound UDP isn't even
// queued.
try { try {
kernel.closeEndpoint(this); kernel.closeEndpoint(this);
} catch( IOException e ) { } catch( IOException e ) {

Loading…
Cancel
Save