Added test classes for the networking and made so that the network engine sends object insted of raw data

This commit is contained in:
Ziver Koc 2007-06-03 19:20:26 +00:00
parent a0363aa3d8
commit 16b9f1f265
11 changed files with 161 additions and 53 deletions

View file

@ -8,6 +8,7 @@ import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider; import java.nio.channels.spi.SelectorProvider;
import ei.engine.network.response.ResponseEvent; import ei.engine.network.response.ResponseEvent;
import ei.engine.network.util.Converter;
public class NioClient extends NioNetwork{ public class NioClient extends NioNetwork{
@ -32,4 +33,8 @@ public class NioClient extends NioNetwork{
SocketChannel socket = initiateConnection(new InetSocketAddress(hostAddress, port)); SocketChannel socket = initiateConnection(new InetSocketAddress(hostAddress, port));
send(socket, handler, data); send(socket, handler, data);
} }
public void send(ResponseEvent handler, Object data) throws IOException {
send(handler, Converter.toBytes(data));
}
} }

View file

@ -16,9 +16,13 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import ei.engine.network.message.Message;
import ei.engine.network.message.StringMessage;
import ei.engine.network.message.type.SystemMessage;
import ei.engine.network.response.PrintRsp; import ei.engine.network.response.PrintRsp;
import ei.engine.network.response.ResponseEvent; import ei.engine.network.response.ResponseEvent;
import ei.engine.network.server.ClientData; import ei.engine.network.server.ClientData;
import ei.engine.network.util.Converter;
import ei.engine.network.worker.EchoWorker; import ei.engine.network.worker.EchoWorker;
import ei.engine.network.worker.Worker; import ei.engine.network.worker.Worker;
import ei.engine.util.MultiPrintStream; import ei.engine.util.MultiPrintStream;
@ -40,6 +44,7 @@ public abstract class NioNetwork implements Runnable {
// The buffer into which we'll read data when it's available // The buffer into which we'll read data when it's available
protected ByteBuffer readBuffer = ByteBuffer.allocate(8192); protected ByteBuffer readBuffer = ByteBuffer.allocate(8192);
protected Worker worker; protected Worker worker;
protected Worker systemWorker;
// This map contains all the clients that are conncted // This map contains all the clients that are conncted
protected Map<InetSocketAddress, ClientData> clients = new HashMap<InetSocketAddress, ClientData>(); protected Map<InetSocketAddress, ClientData> clients = new HashMap<InetSocketAddress, ClientData>();
@ -82,6 +87,23 @@ public abstract class NioNetwork implements Runnable {
this.worker = worker; this.worker = worker;
} }
public void send(SocketChannel socket, Object data) {
send(socket, Converter.toBytes(data));
}
public void send(InetSocketAddress address, Object data){
send(address, Converter.toBytes(data));
}
public void send(InetSocketAddress address, byte[] data){
send(getSocketChannel(address), data);
}
public void send(SocketChannel socket, ResponseEvent handler, Object data) throws IOException {
send(socket, handler, Converter.toBytes(data));
}
public void send(SocketChannel socket, ResponseEvent handler, byte[] data) throws IOException { public void send(SocketChannel socket, ResponseEvent handler, byte[] data) throws IOException {
// Register the response handler // Register the response handler
rspEvents.put(socket, handler); rspEvents.put(socket, handler);
@ -103,10 +125,6 @@ public abstract class NioNetwork implements Runnable {
} }
} }
public void send(InetSocketAddress address, byte[] data){
send(getSocketChannel(address), data);
}
/** /**
* Queues the message to be sent and wakeups the selector * Queues the message to be sent and wakeups the selector
* *
@ -171,9 +189,11 @@ public abstract class NioNetwork implements Runnable {
} }
else if (key.isReadable()) { else if (key.isReadable()) {
read(key); read(key);
//System.out.println("Reading");
} }
else if (key.isWritable()) { else if (key.isWritable()) {
write(key); write(key);
//System.out.println("Writing");
} }
} }
} }
@ -235,17 +255,32 @@ public abstract class NioNetwork implements Runnable {
return; return;
} }
if(rspEvents.get(socketChannel) != null){ // Make a correctly sized copy of the data before handing it
// to the client
byte[] rspByteData = new byte[numRead];
System.arraycopy(readBuffer.array(), 0, rspByteData, 0, numRead);
Object rspData = Converter.toObject(rspByteData);
if(rspData instanceof SystemMessage){
if(systemWorker != null){
systemWorker.processData(this, socketChannel, rspData);
}
else{
System.out.println("Unhandled System Message!!!");
}
}
else if(rspEvents.get(socketChannel) != null){
// Handle the response // Handle the response
handleResponse(socketChannel, readBuffer.array(), numRead); handleResponse(socketChannel, rspData);
} }
else{ else{
// Hand the data off to our worker thread // Hand the data off to our worker thread
if(worker != null){ if(worker != null){
worker.processData(this, socketChannel, readBuffer.array(), numRead); worker.processData(this, socketChannel, rspData);
} }
else{ else{
System.out.println("Unhandled Message Removed!!!"); System.out.println("Unhandled Message!!!");
} }
} }
} }
@ -279,12 +314,8 @@ public abstract class NioNetwork implements Runnable {
/** /**
* Client And Server ResponseEvent * Client And Server ResponseEvent
*/ */
private void handleResponse(SocketChannel socketChannel, byte[] data, int numRead) throws IOException { private void handleResponse(SocketChannel socketChannel, Object rspData) throws IOException {
// Make a correctly sized copy of the data before handing it
// to the client
byte[] rspData = new byte[numRead];
System.arraycopy(data, 0, rspData, 0, numRead);
// Look up the handler for this channel // Look up the handler for this channel
ResponseEvent handler = (ResponseEvent) rspEvents.get(socketChannel); ResponseEvent handler = (ResponseEvent) rspEvents.get(socketChannel);
@ -348,30 +379,4 @@ public abstract class NioNetwork implements Runnable {
// Register an interest in writing on this channel // Register an interest in writing on this channel
key.interestOps(SelectionKey.OP_WRITE); key.interestOps(SelectionKey.OP_WRITE);
} }
public static void main(String[] args) {
try {
EchoWorker worker = new EchoWorker();
new Thread(worker).start();
NioNetwork server = new NioServer(null, 9090);
server.setWorker(worker);
new Thread(server).start();
NioClient client = new NioClient(InetAddress.getByName("localhost"), 9090);
Thread t = new Thread(client);
t.setDaemon(false);
t.start();
for(int i=0;;i++){
PrintRsp handler = new PrintRsp();
client.send(handler, ("LOL: "+i).getBytes());
handler.waitForResponse();
System.out.println("sending");
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("closing");
}
} }

View file

@ -0,0 +1,23 @@
package ei.engine.network.message;
public class StringMessage extends Message {
private static final long serialVersionUID = 1L;
private String msg;
public StringMessage(String msg){
this.msg = msg;
}
public String getString(){
return msg;
}
public void setString(String msg){
this.msg = msg;
}
public String toString(){
return getString();
}
}

View file

@ -3,8 +3,8 @@ package ei.engine.network.response;
public class PrintRsp extends ResponseEvent{ public class PrintRsp extends ResponseEvent{
@Override @Override
protected void responseEvent(byte[] rsp) { protected void responseEvent(Object rsp) {
System.out.println(new String(rsp)); System.out.println(rsp);
} }
} }

View file

@ -2,9 +2,9 @@ package ei.engine.network.response;
public abstract class ResponseEvent { public abstract class ResponseEvent {
private byte[] rsp = null; private Object rsp = null;
public synchronized boolean handleResponse(byte[] rsp) { public synchronized boolean handleResponse(Object rsp) {
this.rsp = rsp; this.rsp = rsp;
notify(); notify();
return true; return true;
@ -31,5 +31,5 @@ public abstract class ResponseEvent {
return (rsp != null); return (rsp != null);
} }
protected abstract void responseEvent(byte[] rsp); protected abstract void responseEvent(Object rsp);
} }

View file

@ -48,4 +48,20 @@ public class Converter {
} }
return object; return object;
} }
/**
* Checks if the given interface is implemented in the object
* @param object The object to look for the interface
* @param interf The interface to look for
* @return True if the interface is implemented else false
*/
public static boolean isInstanceOf(Object object, Class interf){
Class[] objectInterf = object.getClass().getInterfaces();
for(int i=0; i<objectInterf.length ;i++){
if(objectInterf[i] == interf){
return true;
}
}
return false;
}
} }

View file

@ -1,11 +1,24 @@
package ei.engine.network.worker; package ei.engine.network.worker;
import ei.engine.network.NioNetwork;
public class SystemWorker extends Worker { public class SystemWorker extends Worker {
public SystemWorker(NioNetwork nio){
}
@Override
public void run() {
try{
Thread.sleep(1000);
}catch(Exception e){}
}
@Override @Override
public void update() { public void update() {
// TODO Auto-generated method stub
} }
} }

View file

@ -9,11 +9,9 @@ import ei.engine.network.NioNetwork;
public abstract class Worker implements Runnable { public abstract class Worker implements Runnable {
private List<WorkerDataEvent> queue = new LinkedList<WorkerDataEvent>(); private List<WorkerDataEvent> queue = new LinkedList<WorkerDataEvent>();
public void processData(NioNetwork server, SocketChannel socket, byte[] data, int count) { public void processData(NioNetwork server, SocketChannel socket, Object data) {
byte[] dataCopy = new byte[count];
System.arraycopy(data, 0, dataCopy, 0, count);
synchronized(queue) { synchronized(queue) {
queue.add(new WorkerDataEvent(server, socket, dataCopy)); queue.add(new WorkerDataEvent(server, socket, data));
queue.notify(); queue.notify();
} }
} }

View file

@ -7,9 +7,9 @@ import ei.engine.network.NioNetwork;
class WorkerDataEvent { class WorkerDataEvent {
public NioNetwork network; public NioNetwork network;
public SocketChannel socket; public SocketChannel socket;
public byte[] data; public Object data;
public WorkerDataEvent(NioNetwork server, SocketChannel socket, byte[] data) { public WorkerDataEvent(NioNetwork server, SocketChannel socket, Object data) {
this.network = server; this.network = server;
this.socket = socket; this.socket = socket;
this.data = data; this.data = data;

View file

@ -0,0 +1,27 @@
package ei.engine.test;
import java.io.IOException;
import java.net.InetAddress;
import ei.engine.network.NioClient;
import ei.engine.network.message.StringMessage;
import ei.engine.network.response.PrintRsp;
public class NetworkClient {
public static void main(String[] args) {
try {
NioClient client = new NioClient(InetAddress.getByName("localhost"), 6056);
Thread t = new Thread(client);
t.setDaemon(false);
t.start();
for(int i=0;;i++){
PrintRsp handler = new PrintRsp();
client.send(handler, new StringMessage("StringMessage: "+i));
handler.waitForResponse();
//System.out.println("sending");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,21 @@
package ei.engine.test;
import java.io.IOException;
import ei.engine.network.NioNetwork;
import ei.engine.network.NioServer;
import ei.engine.network.worker.EchoWorker;
public class NetworkServer {
public static void main(String[] args) {
try {
EchoWorker worker = new EchoWorker();
new Thread(worker).start();
NioNetwork server = new NioServer(null, 6056);
server.setWorker(worker);
new Thread(server).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}