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
This commit is contained in:
parent
0d23903830
commit
b46a09066d
@ -409,14 +409,12 @@ public class DefaultServer implements Server
|
||||
m.setReliable( true );
|
||||
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
|
||||
// fast will be cleaned up as a side-effect
|
||||
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 );
|
||||
|
||||
/**
|
||||
* Closes this endpoint.
|
||||
* Closes this endpoint without flushing any of its
|
||||
* currently enqueued outbound data.
|
||||
*/
|
||||
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
|
||||
{
|
||||
protected static final ByteBuffer CLOSE_MARKER = ByteBuffer.allocate(0);
|
||||
|
||||
private long id;
|
||||
private SocketChannel socket;
|
||||
private SelectorKernel kernel;
|
||||
private ConcurrentLinkedQueue<ByteBuffer> outbound = new ConcurrentLinkedQueue<ByteBuffer>();
|
||||
private boolean closing = false;
|
||||
|
||||
public NioEndpoint( SelectorKernel kernel, long id, SocketChannel socket )
|
||||
{
|
||||
@ -69,6 +72,21 @@ public class NioEndpoint implements Endpoint
|
||||
|
||||
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 {
|
||||
kernel.closeEndpoint(this);
|
||||
} catch( IOException e ) {
|
||||
@ -142,7 +160,13 @@ public class NioEndpoint implements Endpoint
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
@ -354,6 +354,14 @@ public class SelectorKernel extends AbstractKernel
|
||||
|
||||
// We will send what we can and move on.
|
||||
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 );
|
||||
|
||||
// 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()
|
||||
{
|
||||
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 {
|
||||
kernel.closeEndpoint(this);
|
||||
} catch( IOException e ) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user