Tutorial Issues

My client looks like this;

[java]package mygame;



import com.jme3.network.connection.Client;

import com.jme3.network.message.Message;

import com.jme3.network.serializing.Serializable;

import com.jme3.network.serializing.Serializer;

import java.io.IOException;



public class ClientMain {



public static void main(String[] args) throws IOException {

Client client = new Client(“localhost”, 28642, 28643);



Serializer.registerClass(HelloMessage.class);



client.addMessageListener(this, HelloMessage.class);

client.send(new HelloMessage());



client.start();

}



@Serializable()

public class HelloMessage extends Message {



public String hello = “Hello!”;

}



public void messageReceived(Message message) throws IOException {

// This message is of type HelloMessage, so we don’t have to check.

HelloMessage helloMessage = (HelloMessage) message;

System.out.println(helloMessage.hello);

helloMessage.hello = “Hi!”;

message.getClient().send(helloMessage);

}

}[/java]



My server;

[java]package mygame;



import com.jme3.network.connection.Server;

import com.jme3.network.message.Message;

import com.jme3.network.serializing.Serializable;

import com.jme3.network.serializing.Serializer;

import java.io.IOException;



public class ServerMain{



@Serializable()

public class HelloMessage extends Message {



public String hello = “Hello!”;

}



public static void main(String[] args) throws IOException {

Server myServer = new Server(28642, 28643);



Serializer.registerClass(HelloMessage.class);



myServer.addMessageListener(this, HelloMessage.class);



myServer.start();

}





public void messageReceived(Message message) throws IOException{

// This message is of type HelloMessage, so we don’t have to check.

HelloMessage helloMessage = (HelloMessage) message;

System.out.println(helloMessage.hello);

helloMessage.hello = “Hi!”;

message.getClient().send(helloMessage);

}

}

[/java]



What am I doing wrong here? I’ve tried to follow the tutorial but the the fragments don’t combine together to make functioning programs for me. The problem seems to be with adding the message listeners. Please send help.

Always use start() before starting to send messages. Also, once you start() the client, it’s going to connect. This can take a bit, so I recommend adding a ConnectionListener to your client class, and on ‘clientConnected(Client)’ send the message.

The trouble is that the lines;

[java]myServer.addMessageListener(this, HelloMessage.class);[/java]

In my server, and



[java]client.addMessageListener(this, HelloMessage.class);[/java]

in my client both give me the compiler error…



[java]C:UsersEricjMonkeyProjectsServerSidesrcmygameServerMain.java:22: non-static variable this cannot be referenced from a static context

myServer.addMessageListener(this, HelloMessage.class);

C:UsersEricjMonkeyProjectsServerSidesrcmygameServerMain.java:22: cannot find symbol

symbol : method addMessageListener(mygame.ServerMain,java.lang.Class<mygame.ServerMain.HelloMessage>)

location: class com.jme3.network.connection.Server

myServer.addMessageListener(this, HelloMessage.class);

[/java]

(interchange Server for Client and the other error is identical)



If I remove the static keyword from my main method then I can’t run the program because it fails to find a main method.

Oh yeah, I missed that. You need to instantiate ClientMain and ServerMain first, to escape staticness.



Your client code changed to where it’ll work:



package mygame;



import com.jme3.network.connection.Client;

import com.jme3.network.message.Message;

import com.jme3.network.serializing.Serializable;

import com.jme3.network.serializing.Serializer;

import java.io.IOException;



public class ClientMain {



public static void main(String[] args) throws IOException {

Client client = new Client(“localhost”, 28642, 28643);



Serializer.registerClass(HelloMessage.class);



client.addMessageListener(new ClientMain(), HelloMessage.class);

client.send(new HelloMessage());



client.start();

}



@Serializable()

public class HelloMessage extends Message {



public String hello = “Hello!”;

}



public void messageReceived(Message message) throws IOException {

// This message is of type HelloMessage, so we don’t have to check.

HelloMessage helloMessage = (HelloMessage) message;

System.out.println(helloMessage.hello);

helloMessage.hello = “Hi!”;

message.getClient().send(helloMessage);

}

}

Doesn’t work.

line 16 - cannot find symbol addMessageListener(mygame.ClientMain,java.lang.Class<mygame.ClientMain.HelloMessage>)

location: class com.jme3.network.connection.Client



line 17 - non-static variable this cannot be referenced from a static context

Oops.





public class ClientMain implements MessageListener



But then you need to implement all MessageListener’s methods, or



public class ClientMain extends MessageAdapter



Where you can choose which to override.



And HelloMessage would need to be a static class for this to work.

Alright they run and connect now! :slight_smile:



However they don’t send the message.



The Client errors;

[java]Exception in thread “main” java.nio.channels.NotYetConnectedException

at sun.nio.ch.SocketChannelImpl.ensureWriteOpen(SocketChannelImpl.java:130)

at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:324)

at com.jme3.network.connection.TCPConnection.send(TCPConnection.java:245)

at com.jme3.network.connection.TCPConnection.sendObject(TCPConnection.java:206)

at com.jme3.network.connection.Client.send(Client.java:225)

at mygame.ClientMain.main(ClientMain.java:22)[/java]



The program doesn’t stop though, they remain running and connected.



Any ideas?

Yeah, as said before you need to either wait like 2 seconds before trying to send anything, or place your send call in the ConnectionListener.



Wait method (not recommended, since it assumes it connects fine)

[java]

package mygame;



import com.jme3.network.connection.Client;

import com.jme3.network.message.Message;

import com.jme3.network.serializing.Serializable;

import com.jme3.network.serializing.Serializer;

import java.io.IOException;



public class ClientMain extends MessageAdapter {



public static void main(String[] args) throws IOException {

Client client = new Client(“localhost”, 28642, 28643);



Serializer.registerClass(HelloMessage.class);



client.addMessageListener(new ClientMain(), HelloMessage.class);

client.start();



try {

Thread.sleep(2000);

} catch (Exception e) {}

client.send(new HelloMessage());

}



@Serializable()

public static class HelloMessage extends Message {



public String hello = “Hello!”;

}



public void messageReceived(Message message) throws IOException {

// This message is of type HelloMessage, so we don’t have to check.

HelloMessage helloMessage = (HelloMessage) message;

System.out.println(helloMessage.hello);

helloMessage.hello = “Hi!”;

message.getClient().send(helloMessage);

}

}

[/java]



ConnectionListener method (recommended)

[java]

package mygame;



import com.jme3.network.connection.Client;

import com.jme3.network.message.Message;

import com.jme3.network.serializing.Serializable;

import com.jme3.network.serializing.Serializer;

import java.io.IOException;



public class ClientMain extends MessageAdapter implements ConnectionListener {

public static Client client; // Static variable client so it’s okay to set in main. Also not recommended, but passable.

public static void main(String[] args) throws IOException {

client = new Client(“localhost”, 28642, 28643);



Serializer.registerClass(HelloMessage.class);



ClientMain clientMain = new ClientMain();

client.addMessageListener(clientMain, HelloMessage.class);

client.addConnectionListener(clientMain);

client.start();

}



@Serializable()

public static class HelloMessage extends Message {



public String hello = “Hello!”;

}



public void messageReceived(Message message) throws IOException {

// This message is of type HelloMessage, so we don’t have to check.

HelloMessage helloMessage = (HelloMessage) message;

System.out.println(helloMessage.hello);

helloMessage.hello = “Hi!”;

message.getClient().send(helloMessage);

}



public void clientConnected(Client client) {

// Watch it, when used on a Client, the client parameter will be null.

client.send(new HelloMessage());

}

}

[/java]



I have not tested this, but should work if I’m not missing anything :slight_smile:

1 Like

This is how I did it, your code plus I had to implement the clientDisconnected and wrap the client.send inside a try/catch.

[java]package mygame;



import com.jme3.network.connection.Client;

import com.jme3.network.events.ConnectionListener;

import com.jme3.network.events.MessageAdapter;

import com.jme3.network.message.Message;

import com.jme3.network.serializing.Serializable;

import com.jme3.network.serializing.Serializer;

import java.io.IOException;



public class ClientMain extends MessageAdapter implements ConnectionListener {



public static Client client;



public static void main(String[] args) throws IOException {

client = new Client(“localhost”, 28642, 28643);



Serializer.registerClass(HelloMessage.class);



ClientMain clientMain = new ClientMain();

client.addMessageListener(clientMain, HelloMessage.class);

client.addConnectionListener(clientMain);



client.start();

}



@Serializable()

public static class HelloMessage extends Message {



public String hello = “Hello!”;

}



@Override

public void messageReceived(Message message) {

// This message is of type HelloMessage, so we don’t have to check.

HelloMessage helloMessage = (HelloMessage) message;

System.out.println(helloMessage.hello);

helloMessage.hello = “Hi!”;

try {

message.getClient().send(helloMessage);

} catch (IOException e) {System.out.println(e);}

}



public void clientConnected(Client client) {

// Watch it, when used on a Client, the client parameter will be null.

try{client.send(new HelloMessage());}catch(IOException e){System.out.println(e);}

}



public void clientDisconnected(Client client) {

throw new UnsupportedOperationException(“Not supported yet.”);

}

}[/java]



Of course that didn’t work for me either, my luck is terrible. :frowning:

[java]Exception in thread “Thread-1” java.lang.NullPointerException

at mygame.ClientMain.clientConnected(ClientMain.java:46)

at com.jme3.network.connection.Connection.fireClientConnected(Connection.java:384)

at com.jme3.network.connection.TCPConnection.connect(TCPConnection.java:99)

at com.jme3.network.connection.Connection.run(Connection.java:133)

at com.jme3.network.connection.ConnectionRunnable.run(ConnectionRunnable.java:77)

at java.lang.Thread.run(Thread.java:619)[/java]



At this point I feel it is apparent that I am not understanding this. Afterall I have NO experience in networking, but that’s what I was hoping to get through this. Is there any other resources you could recommend for me to learn game networking from a basic start?

[java]

try{client.send(new HelloMessage());}catch(IOException e){System.out.println(e);}

[/java]

client is null, remember?:stuck_out_tongue: use try{this.client…etc}

That worked, sort of! haha here’s what happens now;



SERVERSIDE;

[java]INFO: [Server#1][???] Started server.

Oct 11, 2010 10:32:31 AM com.jme3.network.connection.TCPConnection accept

INFO: [Server#1][TCP] A client connected with address /127.0.0.1

Hello!

Hello!

IOException!

Oct 11, 2010 10:32:31 AM com.jme3.network.connection.Connection run

SEVERE: [Server#1][???] Error while selecting. Message: An existing connection was forcibly closed by the remote host

Oct 11, 2010 10:32:31 AM com.jme3.network.connection.Connection run

SEVERE: [Server#1][???] Error while selecting. Message: An existing connection was forcibly closed by the remote host

Hello!

IOException!

Oct 11, 2010 10:32:31 AM com.jme3.network.connection.ClientManager messageReceived

SEVERE: [ClientManager][???] Something went wrong in the client registration process.

Oct 11, 2010 10:32:31 AM com.jme3.network.connection.Connection run

SEVERE: [Server#1][???] Error while selecting. Message: An existing connection was forcibly closed by the remote host

Oct 11, 2010 10:32:31 AM com.jme3.network.connection.ClientManager messageReceived

SEVERE: [ClientManager][???] Something went wrong in the client registration process.

Hello!

IOException![/java]



CLIENTSIDE;

[java]INFO: [Client#1][TCP] Connection succeeded.

Exception in thread “Thread-1” java.lang.NullPointerException

Hi!

at mygame.ClientMain.messageReceived(ClientMain.java:40)

at com.jme3.network.connection.Connection.fireMessageReceived(Connection.java:339)

at com.jme3.network.connection.TCPConnection.read(TCPConnection.java:182)

at com.jme3.network.connection.Connection.run(Connection.java:124)

at com.jme3.network.connection.ConnectionRunnable.run(ConnectionRunnable.java:77)

at java.lang.Thread.run(Thread.java:619)[/java]



any ideas? and also! as it is apparent that I am bad at this, where are some good BEGINNER tutorials on understanding this networking? Cause I really want to learn game networking but resources are hard to find.

@sarophym



Sorry, finding beginner tutorials for intermediate/advanced topics is hard. Did you google for “networking client server java tutorial” and look up terms you didn’t understand in Wikipedia etc?

Anyway, the Sun tutorial is here:

http://download.oracle.com/javase/tutorial/networking/TOC.html



@Levia



Could you please add import statements to you code samples, or at least mention the packages?

Or even better, do you maybe have a simple sample app (probably rather two, client and server) that you could share?



Has anyone ever tried combining networking with physics? I thought about it recently and it’s certainly not trivial to prevent such a game from getting out of sync. Do you let the server app calculate the physics and then constantly send the absolute locations to the (non-physical) clients… or what? :?

I’m intending on combining the networking with physics… I believe I’m in over my head, but I’m determined.

sarophym said:
I'm intending on combining the networking with physics... I believe I'm in over my head, but I'm determined.
You are very much indeed in over your head good sir. Might I kindly suggest you set some simpler goals for yourself until we have some actual proof-of-concepts, like working games, that you can look at for some straight forward reference? To be honest, right now the helpful developers are making your game more so than you are, if you get what I mean.

Build a treehouse before attempting a castle :)

@zathras Gotcha on the imports and yes a complete example app is in the pipeline. Just a bit busy lately :slight_smile: I’ll have more time really soon (I’m talking weekend + next week (I have a few days off from school then)).