The wiki doc is out of date but is still only off slightly. I will get to it when I do Networking but I did spend 1 day with it recently and learned some things.
What I learned from that 1 day, take it for what its worth.
Initialize Messaging on server only and do it before starting server.
try {
server = Network.createServer(NetworkMessaging.PORT);
NetworkMessaging.initialiseSerializables();
server.start();
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
The server class,
package myserver;
import network.util.CreateGeoms;
import com.jme3.app.SimpleApplication;
import com.jme3.math.ColorRGBA;
import com.jme3.network.Network;
import com.jme3.network.Server;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.system.JmeContext;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import network.util.NetworkMessaging;
import network.util.NetworkMessaging.NetworkMessage;
public class ServerMain extends SimpleApplication {
private Server server;
private float count;
private static final Logger LOG = Logger.getLogger(ServerMain.class.getName());
public ServerMain() {
count = 0;
}
public static void main(String[] args) {
ServerMain app = new ServerMain();
app.start(JmeContext.Type.Headless);
}
@Override
public void simpleInitApp() {
try {
server = Network.createServer(NetworkMessaging.PORT);
NetworkMessaging.initialiseSerializables();
server.start();
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
Geometry geom = new CreateGeoms(this).createGeom(ColorRGBA.Blue);
rootNode.attachChild(geom);
}
@Override
public void simpleUpdate(float tpf) {
count += tpf;
if (count > 3f) {
server.broadcast(new NetworkMessage("Welcome to the playground. " + tpf));
count = 0;
}
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
@Override
public void destroy() {
server.close();
super.destroy();
}
}
The client and server need the same messaging classes. This means when you use separate client/server projects, you will need a shared jar/library that contains them.
Messaging class example,
package network.util;
import com.jme3.math.Vector3f;
import com.jme3.network.AbstractMessage;
import com.jme3.network.serializing.Serializable;
import com.jme3.network.serializing.Serializer;
public class NetworkMessaging {
public static final int PORT = 6000;
public static void initialiseSerializables() {
Serializer.registerClass(NetworkMessage.class);
Serializer.registerClass(PosAndLocMessage.class);
Serializer.registerClass(PositionMessage.class);
}
@Serializable
public static class NetworkMessage extends AbstractMessage {
private String message;
public NetworkMessage() {
}
public NetworkMessage(String message) {
this.message = message;
}
/**
* @return the message
*/
public String getMessage() {
return message;
}
}
@Serializable
public static class PosAndLocMessage extends AbstractMessage {
private Vector3f position;
private Vector3f direction;
public PosAndLocMessage() {
}
public PosAndLocMessage(Vector3f position, Vector3f direction) {
this.position = position;
this.direction = direction;
}
/**
* @return the position
*/
public Vector3f getPosition() {
return position;
}
/**
* @return the direction
*/
public Vector3f getDirection() {
return direction;
}
}
@Serializable
public static class PositionMessage extends AbstractMessage {
private Vector3f position;
public PositionMessage() {
}
public PositionMessage(Vector3f position) {
this.position = position;
}
/**
* @return the position
*/
public Vector3f getPosition() {
return position;
}
}
}
An example of client startup using a shared jar/library that contains the message classes,
package myclient;
import com.jme3.app.SimpleApplication;
import com.jme3.math.ColorRGBA;
import com.jme3.network.Client;
import com.jme3.network.Network;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.system.JmeContext;
import java.io.IOException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import network.util.CreateGeoms;
import network.util.NetworkMessaging;
public class ClientMain extends SimpleApplication {
private Client client;
private static final Logger LOG = Logger.getLogger(ClientMain.class.getName());
private ConcurrentLinkedQueue<String> messageQueue;
public static void main(String[] args) {
ClientMain app = new ClientMain();
app.start(JmeContext.Type.Display);
}
@Override
public void simpleInitApp() {
try {
client = Network.connectToServer("localhost", NetworkMessaging.PORT);
client.start();
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
messageQueue = new ConcurrentLinkedQueue<>();
client.addMessageListener(new NetworkMessageListener(messageQueue));
Geometry geom = new CreateGeoms(this).createGeom(ColorRGBA.Blue);
rootNode.attachChild(geom);
}
@Override
public void simpleUpdate(float tpf) {
String message = messageQueue.poll();
if (message != null) {
this.fpsText.setText(message);
}
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
@Override
public void destroy() {
client.close();
super.destroy();
}
}
an example of a Client message listener,
package myclient;
import com.jme3.network.Client;
import com.jme3.network.Message;
import com.jme3.network.MessageListener;
import java.util.concurrent.ConcurrentLinkedQueue;
import network.util.NetworkMessaging.NetworkMessage;
public class NetworkMessageListener implements MessageListener<Client> {
private final ConcurrentLinkedQueue<String> messageQueue;
public NetworkMessageListener(ConcurrentLinkedQueue<String> messageQueue) {
this.messageQueue = messageQueue;
}
@Override
public void messageReceived(Client source, Message m) {
if (m instanceof NetworkMessage) {
NetworkMessage message = (NetworkMessage) m;
messageQueue.add(message.getMessage());
}
}
}
Last,
see these videos
https://jmonkeyengine.github.io/wiki/jme3/advanced/networking_video_tutorials.html
starting from
•Video: Introduction to SpiderMonkey (Part 1/2)
Although dated, I was able to get a working SpiderMonkey server/client up and running with 0 networking experience and outdated wiki pages.
If anyone sees problems with this code please say so because this is what I will be using to update the wiki page.
Hope this helps in some way…