UDP-based kernel now does its writes on a background
thread. Most of the time UDP packets go right out but not always... depending on the network layer it can take a couple of milliseconds. And that's alot when you're blasting packets out to a dozen users 20 times a second. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7245 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
1f1c2ac15b
commit
593d9bf35a
@ -114,10 +114,17 @@ public class UdpEndpoint implements Endpoint
|
|||||||
if( !isConnected() ) {
|
if( !isConnected() ) {
|
||||||
throw new KernelException( "Endpoint is not connected:" + this );
|
throw new KernelException( "Endpoint is not connected:" + this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DatagramPacket p = new DatagramPacket( data.array(), data.position(),
|
DatagramPacket p = new DatagramPacket( data.array(), data.position(),
|
||||||
data.remaining(), address );
|
data.remaining(), address );
|
||||||
socket.send(p);
|
|
||||||
|
// Just queue it up for the kernel threads to write
|
||||||
|
// out
|
||||||
|
kernel.enqueueWrite( this, p );
|
||||||
|
|
||||||
|
//socket.send(p);
|
||||||
} catch( IOException e ) {
|
} catch( IOException e ) {
|
||||||
throw new KernelException( "Error sending datagram to:" + address, e );
|
throw new KernelException( "Error sending datagram to:" + address, e );
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ import java.net.*;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -57,6 +59,8 @@ public class UdpKernel extends AbstractKernel
|
|||||||
private InetSocketAddress address;
|
private InetSocketAddress address;
|
||||||
private HostThread thread;
|
private HostThread thread;
|
||||||
|
|
||||||
|
private ExecutorService writer = Executors.newFixedThreadPool(2);
|
||||||
|
|
||||||
// The nature of UDP means that even through a firewall,
|
// The nature of UDP means that even through a firewall,
|
||||||
// a user would have to have a unique address+port since UDP
|
// a user would have to have a unique address+port since UDP
|
||||||
// can't really be NAT'ed.
|
// can't really be NAT'ed.
|
||||||
@ -104,6 +108,7 @@ public class UdpKernel extends AbstractKernel
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
thread.close();
|
thread.close();
|
||||||
|
writer.shutdown();
|
||||||
thread = null;
|
thread = null;
|
||||||
} catch( IOException e ) {
|
} catch( IOException e ) {
|
||||||
throw new KernelException( "Error closing host connection:" + address, e );
|
throw new KernelException( "Error closing host connection:" + address, e );
|
||||||
@ -120,8 +125,13 @@ public class UdpKernel extends AbstractKernel
|
|||||||
if( reliable )
|
if( reliable )
|
||||||
throw new UnsupportedOperationException( "Reliable send not supported by this kernel." );
|
throw new UnsupportedOperationException( "Reliable send not supported by this kernel." );
|
||||||
|
|
||||||
// We ignore the copy flag because we know all outbound traffic
|
if( copy )
|
||||||
// goes instantly.
|
{
|
||||||
|
// Copy the data just once
|
||||||
|
byte[] temp = new byte[data.remaining()];
|
||||||
|
System.arraycopy(data.array(), data.position(), temp, 0, data.remaining());
|
||||||
|
data = ByteBuffer.wrap(temp);
|
||||||
|
}
|
||||||
|
|
||||||
// Hand it to all of the endpoints that match our routing
|
// Hand it to all of the endpoints that match our routing
|
||||||
for( UdpEndpoint p : socketEndpoints.values() ) {
|
for( UdpEndpoint p : socketEndpoints.values() ) {
|
||||||
@ -177,6 +187,40 @@ public class UdpKernel extends AbstractKernel
|
|||||||
addEnvelope( env );
|
addEnvelope( env );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void enqueueWrite( Endpoint endpoint, DatagramPacket packet )
|
||||||
|
{
|
||||||
|
writer.execute( new MessageWriter(endpoint, packet) );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class MessageWriter implements Runnable
|
||||||
|
{
|
||||||
|
private Endpoint endpoint;
|
||||||
|
private DatagramPacket packet;
|
||||||
|
|
||||||
|
public MessageWriter( Endpoint endpoint, DatagramPacket packet )
|
||||||
|
{
|
||||||
|
this.endpoint = endpoint;
|
||||||
|
this.packet = packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
// Not guaranteed to always work but an extra datagram
|
||||||
|
// to a dead connection isn't so big of a deal.
|
||||||
|
if( !endpoint.isConnected() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
thread.getSocket().send(packet);
|
||||||
|
} catch( Exception e ) {
|
||||||
|
KernelException exc = new KernelException( "Error sending datagram to:" + address, e );
|
||||||
|
exc.fillInStackTrace();
|
||||||
|
reportError(exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected class HostThread extends Thread
|
protected class HostThread extends Thread
|
||||||
{
|
{
|
||||||
private DatagramSocket socket;
|
private DatagramSocket socket;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user