RMI alternatives for bidirectional asynchronous calls and callbacks through firewalls or NAT

I am writing a Java based server architecture.

For design reasons, I would like to use asynchronous calls to transfer client actions to the server, as well as asynchronous callbacks to transfer the results (results) of these actions back to the client. Asynchronous calls allow you to buffer client actions. The buffering queue allows simple, mostly single-threaded processing of client actions.

At the moment, my server and client code is pretty symmetrical. They create a registry, then export and bind themselves.

Asynchrony is achieved by buffering incoming actions or results in ConcurrentLinkedQueue. Actual processing is performed by a thread running at regular intervals.

However, this current architecture does not work when clients are firewalls or behind NAT. In this case, the server simply cannot reach the clients in order to push the results to them.

In addition, in this current architecture, the server does not know which client sent this action unless an excessive level of authentication or session processing has been entered. This allows you to fake actions and deceit.


I thought about possible solutions, but did not find a suitable one:

  • The client pulls out, but does not press the server. There may be a method on the server that clients periodically call to get their results. However, this approach seems very ugly; it introduces additional delays, bandwidth, and time issues. Also does not allow fake actions. Direct notifications are also very preferred.

  • TCP connections themselves allow bidirectional communication and can definitely identify clients, so RMI or JRemoting can be hacked to support them, but I don’t know how, and I don’t know about the existing solution.

  • Messaging I am not sure if the messaging framework supports authentication / sessions or client authentication. I would definitely lose the remote methods.

  • I believe that the correct solution would be to find a remote method invocation infrastructure that supports all of the above.


So, in a nutshell, I'm looking for a way:

  • call the server asynchronously or send a message to it
  • call the client asynchronously or pass a message to it, even behind a firewall or NAT
  • identify the client submitting the action
  • it is preferable to be able to call methods, rather than just passing messages
  • save the ability to easily test it with JUnit and Mockito (multiple clients per machine)

Are there any schemes for accessing remote methods that support these? Which one is better?

+4
source share
1 answer

I do not know why you would insist on using RMI or something like that, since it is by definition unidirectional. But I had to learn a similar lesson ... for one of my client-server systems , I implemented something similar to what you have now, using RMI and long-term polls. This turned out to be a terrible mess that was only getting worse and worse.

Then I learned about the wonderful world of publishing-subscribing . This is a natural way to create a client-server application without the need to implement a large number of your own plumbing. Moreover, these structures support such functions as automatic saving, time synchronization, authentication and session permissions, as well as many other materials that you would not want to implement yourself.

In my project, I thwarted all my work and replaced it with CometD , which supports both Java and the browser (Javascript) clients, and could not be happier. This, of course, will support all your needs - asynchronous communication initiated from any side, client identification (and many other functions), and clients behind NAT will not be a problem after the connection is established. It is easy to write tests, too, and the entire infrastructure has been expanded to be able to handle 100 thousand clients, which would be impossible for RMI.

I would strongly recommend that you abandon the requirement for remote method calls. Methods are inherently one-way, but still require a call and a return. It is much better to design a system using event programming .

Update . Since then, I have moved into the world of web applications, in particular, using Meteor .

+5
source

All Articles