views:

150

answers:

5

Hi,

I have one app. that consists of "Manager" and "Worker". Currently, the worker always initiates the connection, says something to the manager, and the manager will send the response.

Since there is a LOT of communication between the Manager and the Worker, I'm considering to have a socket open between the two and do the communication. I'm also hoping to initiate the interaction from both sides - enabling the manager to say something to the worker whenever it wants.

However, I'm a little confused as to how to deal with "collisions". Say, the manager decides to say something to the worker, and at the same time the worker decides to say something to the manager. What will happen? How should such situation be handled?

P.S. I plan to use Netty for the actual implementation.

Thank you very much in advance!

+1  A: 

I think you need to read up on sockets....

You don't really get these kinds of problems....Other than how to responsively handle both receiving and sending, generally this is done through threading your communications... depending on the app you can take a number of approaches to this.

Keith Nicholas
+2  A: 

"I'm also hoping to initiate the interaction from both sides - enabling the manager to say something to the worker whenever it wants."

Simple answer. Don't.

Learn from existing protocols: Have a client and a server. Things will work out nicely. Worker can be the server and the Manager can be a client. Manager can make numerous requests. Worker responds to the requests as they arrive.

Peer-to-peer can be complex with no real value for complexity.

S.Lott
I see. But how should one deal with situations, in which both client and server need to initiate a communication?
Enno Shioji
@Zwei Steinen: First, don't allow client and server to initiate. Client initiates; Server is passive. This leads to the server saving things until the client requests them. If you think you want "real time", you have a very complex problem and need a proper middleware to handle Message Queues.
S.Lott
Thanks for you advice! Right now the client has to periodically poll the server (and it does not work the other way around). Do you think in that situation, introducing a Message Queue is warranted (to avoid the periodical polling)?
Enno Shioji
@Zwei Steinen: introducing a Message Queue is not "warranted". It's "essential", it's "the best practice", it's "the standard solution". Go for it.
S.Lott
+2  A: 

I'd go for a persistent bi-directional channel between server and client.

If all you'll have is one server and one client, then there's no collision issue... If the server accepts a connection, it knows it's the client and vice versa. Both can read and write on the same socket.

Now, if you have multiple clients and your server needs to send a request specifically to client X, then you need handshaking!

When a client boots, it connects to the server. Once this connection is established, the client identifies itself as being client X (the handshake message). The server now knows it has a socket open to client X and every time it needs to send a message to client X, it reuses that socket.

Lucky you, I've just written a tutorial (sample project included) on this precise problem. Using Netty! :)

Here's the link: http://bruno.linker45.eu/2010/07/15/handshaking-tutorial-with-netty/

Notice that in this solution, the server does not attempt to connect to the client. It's always the client who connects to the server. If you were thinking about opening a socket every time you wanted to send a message, you should reconsider persistent connections as they avoid the overhead of connection establishment, consequently speeding up the data transfer rate N-fold.

brunodecarvalho
Wow! Thanks! This is really great :)
Enno Shioji
+1  A: 

The correct link to the Handshake/Netty tutorial mentioned in brunodecarvalho's response is http://bruno.factor45.org/blag/2010/07/15/handshaking-tutorial-with-netty/
I would add this as a comment to his question but I don't have the minimum required reputation to do so.

Pierre
A: 

If you feel like reinventing the wheel and don't want to use middleware...

Design your protocol so that the other peer's answers to your requests are always easily distinguishable from requests from the other peer. Then, choose your network I/O strategy carefully. Whatever code is responsible for reading from the socket must first determine if the incoming data is a response to data that was sent out, or if it's a new request from the peer (looking at the data's header, and whether you've issued a request recently). Also, you need to maintain proper queueing so that when you send responses to the peer's requests it is properly separated from new requests you issue.

Jonathan Rynd