[SOLVED] Best Practise, two way initiated socket communication

Hi there fellow Javaers,

Background story, skip if you want:
[i]After migrating most code from using php as a “server” I moved over to servlets to reuse some checks I already have in java instead of rewriting them in php. Now I took another step and moved over to sockets (mostly so that the server can initiate communication with the clients instead of the clients needing to poll constantly).

As I like to write everything from scratch (I do this mostly to challenge myself anyway and I want to be in control of my code) I already spent something like 15 hours to get sockets up and running to a point where I can send either clear or compressed code to the clients, I have some error handling for socket interruptions and no code is blocking the CPU. My initial tests are extremely satisfying and the performance of the server is great, even with several connected clients.[/i]

Sometimes I want the client to send information to the server and await a response and sometimes I want the server to send information to the applet and await a reply.

What is the best way around this? What if the client sends something to the server and goes into waiting mode, but before the server recieved the request the server initiates a send itself, therefore making the client think that what the client recieves from the server is the response to to the client’s request, while it actually is the request from the server?

I guess I could create two socket connections with the server and bind the server to two ports (one for client initiated and one for server), but there must be a smarter way to solve this, or?

Thanks in advance,
Mike

You can pass something to the server that it passes back so you can correlate what you receive to what you sent. When you receive you shouldn’t be expecting anything specific. Read the bytes, probably create an object from the bytes, then use instanceof to run logic on the object.

Interesting, that’ll throw most of my code upside down :smiley:

So a thread that always listens to everything the server has to say and if it has to do with what I requested in a different thread (which will always be the case) it sends the response back to that thread (and class) based upon the identifier sent to the server?

Sounds quite complicated to me for something that in theory is quite simple :slight_smile: Isn’t it easier to have the server listen to two ports and use the different ports for the differently initiated communications?

Kind regards,
Mike

  1. two threads per connection (reader / writer)
  2. use the selection api (nio)

I’d pair both solutions with a queue in a producer/consumer pattern.

oh, and always let the client connect to the server initially - anything else is error prone.

I heard nio was really difficult (especially as I never programmed anything in the network layer before) but I will have a look at it and see if it can solve the question in one way or another.

I guess I’ll have to go down the path of two threads indeed and pass some identifier with the connection, It’ll take a wrapper class though and some rethinking of my data structure but it’ll save me opening two sockets (which still feels like a good alternative to me :stuck_out_tongue:

If anyone has anything else to throw in I’d appreciate the input, otherwise it’s time for me to start coding :slight_smile:

Thanks to Matzon and Nate! :slight_smile:

Kind regards,
Mike

how would you combine NIO ((probably) one thread per process) with two threads per connection?

I was going for 1 OR 2 - not both :slight_smile:

Ah…

[quote]I’d pair either solution with a queue in a producer/consumer pattern.
[/quote]
… then I’d have understood :persecutioncomplex: silly me.

Haha, I did exactly the same Riven and actually thought of the same question but didn’t dare to ask all mighty Matzon :wink:

I started looking into NIO, noticed it was way above my head and read that it didn’t perform as fast so I’m going down the route of a read and a write thread.

Kind regards,
Mike

Thar be dragons in NIO. Stick with the simpler old IO classes or use a framework that hides the NIO crap.

Not sure why you need to restructure your code so much? First you write something to identify what class is being sent (eg, a String class name or, better, an int or short ID), then you write the bytes for that object. On the other side you read the identifier, create an instance of that class, then read the bytes and populate your instance. Then you have code like this:


if (object instanceof SetPosition) {
   SetPosition setPosition = (SetPosition)object;
   // ...
} else if (object instanceof AddCharacter) {
   AddCharacter addCharacter = (AddCharacter)object;
   // ...
}

Rewrite completed and server initiated communication is in place. It is SO cool to be able to build roads and change the landscape and so on on one computer and it changes instantly on another computer :smiley:

Thanks guys!
Mike