I am new to networking, and I am trying to network a board game that I have created using java.A friend of mine pointed me towards the Kryonet library. So far, it's great. I don't have to deal with sockets!
The problem I'm coming across is sending objects. Mainly, I have a Board type object. This object contains other objects, such as ArrayList objects and Fort objects.
I tried just registering the Board object, but I received these errors:
Exception in thread "Server" com.esotericsoftware.kryo.KryoException: java.lang.
IllegalArgumentException: Class is not registered: Game.Tile
Note: To register this class use: kryo.register(Game.Tile.class);
Serialization trace:
t0 (Game.Board)
at com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.write(FieldSerializer.java:585)
at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:213)
at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:571)
at com.esotericsoftware.kryonet.KryoSerialization.write(KryoSerializatio
n.java:50)
at com.esotericsoftware.kryonet.TcpConnection.send(TcpConnection.java:192)
etc....
Ok fine, Then I will also register Tile.class,
More errors, but then I need to register ArrayList.class - so I register it, and again more errors, so I register Fort.class.
When I register Fort.class, I enter into an infinite loop and get a ton of errors like this:
at com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.write(FieldSerializer.java:564)
at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:213)
at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:504)
at com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.write(FieldSerializer.java:564)
at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:213)
at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:504)
at com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.write(FieldSerializer.java:564)
This leads me to believe I don't quite understand how to register properly and I can't find much information about how to register nested objects. My Fort class is actually an enumerated class but I'm not sure if that makes a difference? Any help would be greatly appreciated!
I have included a class with most of my networking code so you can see an idea of what I am trying to do.
This is my code for the networking:
public class Network extends Listener {
private Server server;
private Client client;
private boolean isServer;
private boolean messageReceived;
private PacketMessage message;
private Board board;
public Network(boolean isServer, Board board) throws IOException {
messageReceived = false;
this.board = board;
this.isServer = isServer;
if (isServer) {
initServer();
// receive();
} else {
initClient();
//probably want to run this in main
client();
}
}
private void initServer() throws IOException {
// 127.0.0.1 means myself
// ports up to 1024 are special and reserved
server = new Server();
registerClasses(server.getKryo());
server.bind(8000, 8001);
// starting a new thread
server.start();
// call my received and my connected
server.addListener(this);
}
private void initClient() throws IOException {
// 127.0.0.1 means myself
// ports up to 1024 are special and reserved
client = new Client();
registerClasses(client.getKryo());
// starting a new thread
client.start();
client.connect(5000, "127.0.0.1", 8000, 8001);
// call my received and call my connected
client.addListener(this);
}
//call in main
//
public void client(){
while(true){
sendRequest();
receive();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// tell Kryo what things it's going to have to send
private void registerClasses(Kryo kryo) {
kryo.register(Request.class);
kryo.register(PacketMessage.class);
kryo.register(Fort.class);
kryo.register(ArrayList.class);
kryo.register(Tile.class);
kryo.register(Board.class);
}
private void sendRequest() {
client.sendTCP(new Request());
}
private void receive() {
messageReceived = false;
while (!messageReceived) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// message.message is really packet.message
System.out.println("Received a message from the host: "
+ message.message);
}
public void received(Connection c, Object p) {
System.out.println("Received Message");
// Is the received packet the same class as PacketMessage.class?
if (p instanceof PacketMessage) {
// Cast it so we can access the message within
// PacketMessage packet =(PacketMessage) p;
// System.out.println("Received a message from the host: "+pa cket.message);
message = (PacketMessage) p;
// We have now received the message!
messageReceived = true;
}
else if (p instanceof Request){
// Create a message packet
PacketMessage packetMessage = new PacketMessage();
// Assign the message text
packetMessage.message = "Hello friend! The time is: "
+ new Date().toString();
// Send the message
//probably want another method to send
c.sendTCP(packetMessage);
c.sendTCP(board);
}
}
// This is run when a connection is received!
public void connected(Connection c) {
System.out.println("Received a connection from "
+ c.getRemoteAddressTCP().getHostString());
}
}