[SOLVED] Inconsistent error registering messages

Thanks for the doc updates.

Note that the automatic serialization setup is optional… but on by default. If your game does not follow these setup guidelines and is otherwise too complicated to fix, it’s simply a matter of removing (unregistering) the serializtion service thing (don’t have the class off the top of my head)… then you can go back to the old “have to do every little thing yourself in exactly the same order” way.

I highly recommend folks let the automatic way work for them, though.

When I rewrite the serialization layer someday, I will build autoregistration into the serializer itself. In the mean time, the service does most of the job with just some setup gotchas for those who haven’t built from one of the templates (because they didn’t know or built before the templates existed). (Though I guess even the basic template might be a poor example in this case because it doesn’t register any of its own classes with the serializer: Examples/network-basic at master · Simsilica/Examples · GitHub)

A quick skim of the rest of the docs seems ok.

1 Like

Do you mean this class?

Yeah, though there is one on the server, too… and you should only have to remove the one on the server, I think.

Yep.
I had a simple server and client setup from when I was learning this that I tested it on. I had already set it up using the automatic registration without knowing why it was done like that.

I updated the wiki to give it more depth on the subject based off your input, thank you.

https://wiki.jmonkeyengine.org/jme3/advanced/networking.html#creating-message-types

1 Like

“you can only do the registrations serverside or you have issues”

Generally i wanted to ask, what in case when application is same for both server+client ?

For now, i register same classes in Serializer like:

if(Serializer.getExactSerializerRegistration(TestMessage.class) == null){
    Serializer.registerClass(TestMessage.class);
}

(so it skip if its already registered right?)

and i dont had issues visible, but want to be sure if this is fine.
If you have some tips, since i start implementing Network, it would be nice.

Due to several key issues in SpiderMonkey, I have moved to Netty.IO.
The largest issue being the object size limits that are imposed due to the way jme serialization works. If size constraints are not a problem, then SpiderMonkey will probably work fine for you.

As for your setup of a client to client connection, whichever one is receiving the connection would be considered the server. Depending on how you app is setup, only register classes when the app is told to listen for a connection. For example when hosting a lan party.

Edit: I think your solution above will work fine too.

1 Like

Are you referring to the case where the server & client are bundled together (like some games do for hosting LAN parties)? If so, when starting the server register the messages exactly once, and when starting the client do nothing. It doesn’t hurt to double-check for an existing registration like you’re doing, but if you follow a safe pattern it’s not strictly necessary either.

1 Like

thanks,

so when App run only Client, then just do not make “Serializer.registerClass” as i understand.
when app runs server or server+client, make “Serializer.registerClass” before init of them.

right?

Also i got some question, i have one problem. i want be able to serialize something like “protected HashMap<Class<? extends A>, A>”, but i cant make “Serializer.registerClass(java.lang.Class.class);” since it require Serializable annotation. Any tips?

Also @tlf30

The largest issue being the object size limits that are imposed due to the way jme serialization works. If size constraints are not a problem, then SpiderMonkey will probably work fine for you.

what do you mean? will i have some problem when sending bigger data like heightmap/alphamap of terrain for example? what are this limits? i thought JME split bigger data into more packages.

Yes, although if the same process runs both server & client you need to ensure that the registration only happens once - you probably need to explicitly disable registration propagation client-side (disable the network client’s serializer service).

You can register classes that are not @Serializable if you provide a custom serializer & de-serializer - see jME’s built-in serializers for examples.

Every message that jME sends must serialize down to < 32K or you’ll get an error when you try to send it. This is more than enough for most gameplay-related packets, but it is an issue for large data like runtime assets (heightmaps, etc). For sending those, I suggest using an embedded HTTP server like Jetty in your server application (MyWorld uses a combination of an embedded HTTP server and client-side caching to implement a fully dynamic asset delivery system).

1 Like

how exactly? well, i anyway register this clases before client is created.

see jME’s built-in serializers for examples.

could you provide link to source please ? :slight_smile: im not sure what Serializers you mean.

Every message that jME sends must serialize down to < 32K or you’ll get an error when you try to send it. This is more than enough for most gameplay-related packets, but it is an issue for large data like runtime assets (heightmaps, etc). For sending those, I suggest using an embedded HTTP server like Jetty in your server application (MyWorld uses a combination of an embedded HTTP server and client-side caching to implement a fully dynamic asset delivery system).

thanks :slight_smile: the only issue seems for me will be some heightmaps/alphamaps/voxel data

but Isnt it possible to send multiple packages then? like send first 100 pixels or block data in each “message”? so could serialize only part of data?

The client uses a network service to receive the registration messages from the server and register the classes client-side. If you have a server & client running in the same process, they’re using the same serializer - so you want to disable this service so that the registrations aren’t done more than once.

https://javadoc.jmonkeyengine.org/v3.3.2-stable/com/jme3/network/service/serializer/ClientSerializerRegistrationsService.html

The serializers are implemented here: JME serializer sources. You can extend the jME Serializer class register it for a non-@Serializable object the same way these are.

Yes, definitely - but it might be more trouble to handle the splitting & re-packing than it would be to use HTTP, which is made for use cases like this. Initially MyWorld implemented a “streams” approach that did exactly this, but it was far more complicated than using the HTTP server. Granted, MyWorld’s network streams probably did a bit more than you’re looking to do - it’s a tradeoff, and for your use case it could easily go either way.

1 Like

Yes, I initially wrote an implementation for splitting and rebuilding larger messages, but it was very painfully and glitchy if the network had issues while the transfer was occurring.

I use HTTP for sending assets to tbe client. For larger things like voxel data I send compressed byte buffers with netty.

1 Like

thanks @danielp @tlf30 :slight_smile:

will follow your advice

1 Like

I only skimmed the recent updates to this thread but I will point out that:

  1. The sim-ethereal examples all let you run the host and client in the same process already. So you can look at those and see how they are done. In general, SpiderMonkey is just fine with this and detects it without and special setup.
  2. “message splitting” is only tricky for UDP streams… for TCP streams it should be pretty straight forward. Send parts, reassemble them when last part comes through.

This could even be standardized if someone wanted to write a special message type and a special message listener that wraps another message listener. I have some code I copy around to do this… but also note that terrain-related data is the only time I’ve ever needed it. So the type of games that need it are a subset of ‘all game types’.

And for reference, the message limit of SpiderMonkey is like 32767 bytes. When I get around to rewriting the serializer it will be unlimited (and you will also be able to send single bits or any bit size for that matter… very useful.)

Edit: for reference on the “host and client in same VM”, all of the network examples here use that approach:

Edit 2: corrected 65536 to 32767.

3 Likes

thanks Paul.

i remember you also had Physics synchronize optimized to lowest amount of bytes as possible. could you link code for it too? thanks :slight_smile:

It’s SimEthereal:

…which is what the sim-eth-basic and sim-eth-es examples use (under the link in my previous message).

1 Like

ok thanks :slight_smile: i thought there would be some specific file i should look at.

If you use SimEthereal then the “lowest amount of bytes possible” thing is automatic.

The wiki page has a getting started link, I think… so you could see how to wire it in your application. (Basically, on the server update tell SimEthereal where things are… client then watches the shared objects and updates local spatials/objects.)

Or you can look at the sim-ethereal examples which are pretty simple game-wise but show the wiring in context along with the client-side tweening considerations that are usually necessary in thread-decoupled state sharing like happens over a network.

1 Like