Networking MessageProtocol refactoring

Just a heads up for users of networking and JME 3.3 that I just did a “possible breaking change” style refactoring of the MessageProtocol class.

Note: it’s only a breaking change if you’ve been calling MessageProtocol directly. a) this is strongly discouraged, and b) the future benefits of the refactoring outweighed the rare possibility that someone is doing this. Plus, it’s an easy change for you if you really need this.

MessageProtocol is now an interface. The various network.base.* classes have been modified for this change. The MessageProtocol can’t be swapped out yet (still hard-coded) but that will be a definite future change.

This change was necessary for two reasons:

  1. I’m trying to change the message buffering to fix the issue related to messages being deserialized in blocks, thus causing the serializer registration message to be processed after potential messages that would require the classes that it is registering. (ie: message 1 is the registration message that would have registered the class that message 2 needs… but they are all deserialized together.)
  2. Someday I want to completely replace the adequate-but-crappy Serializer classes with something based on bitstreams and where the class registration is part of the wire protocol.

Refactoring let’s me easily swap in/out buffer implementations for (1). It also makes (2) possible where it was totally impossible before.

I’ve done some testing locally and everything seems to work at least as well as before. But if you are doing networking with 3.3 and notice new problems then please report them loudly and quickly. Thanks.

4 Likes

The side benefit is that in the refactoring, I discovered that the fix for the serializer registration issue is much easier than I thought. I thought the solution was going to have to be fancier but once all of the various constraints and required buffer copying were reloaded into my brain, the only viable solution turns out to be super simple.

1 Like

Serializer issue should be fixed now. I couldn’t find an actual issue number.

2 Likes

Thanks @pspeed

Just updated to new changes, and I was able to run my project without any issue.

So just to be sure, are we now safe to remove this DelayService from the server?

private class DelayService extends AbstractHostedService {

        private void safeSleep(long ms) {
            try {
                Thread.sleep(ms);
            } catch (InterruptedException e) {
                throw new RuntimeException("Checked exceptions are lame", e);
            }
        }

        @Override
        protected void onInitialize(HostedServiceManager serviceManager) {
            System.out.println("DelayService.onInitialize()");
            //safeSleep(2000);
            //System.out.println("DelayService.delay done");
        }

        @Override
        public void start() {
            System.out.println("DelayService.start()");
            //safeSleep(2000);
            //System.out.println("DelayService.delay done");
        }

        @Override
        public void connectionAdded(Server server, HostedConnection hc) {
            // Just in case
            super.connectionAdded(server, hc);
            System.out.println("DelayService.connectionAdded(" + hc + ")");
            safeSleep(500);
            System.out.println("DelayService.delay done");
        }
    }

Looking forward to this :slightly_smiling_face:

Unfortunately, it seems there is no BitBuffer provided internally by Java. I only found a BitSet.

There are some BitBuffer implementation for Java available on GitHub but not sure if they can be of any help.

The whole approach of using Buffers is dumb in this case. That’s why we have to have a maximum message size, etc. so we can pre-allocate some “max size” buffer for the serializers to write to.

…Java already provided a way to stream data. The Serializer was dumb to use buffers instead.

Anything I do with bits would be stream based… and probably use versions of: https://github.com/Simsilica/SimEthereal/tree/master/src/main/java/com/simsilica/ethereal/io

…ported to JME.

1 Like

Yep. If things are working correctly then this work-around is no longer required.

4 Likes

Awesome!!! Thanks, @pspeed! This has been an annoying issue to work around for quite some time. Glad it’s taken care of!

1 Like