Design Patterns for Multi-Threaded Messaging Server – Best Practices

design-patternsdistributed computingmultithreadingobserver-pattern

I'm designing an instant messaging server as a personal exercise to improve my understanding and application of multi-threading and design patterns in Java. I'm still designing, there's no code yet.

My goal is to have a server that should make effective use of a multi-CPU box. I'd like the server to be distributable across multiple boxes, but wonder if that's running before I can walk.

My initial thoughts are:

  • ClientConnectionManager has ServerSocket object that constantly accepts client Socket connections.
  • ClientConnectionManager has a thread pool that spawns a new ClientProxy object when a client socket connection is accepted, handing in the client Socket object.
  • The ClientProxy objects represent the client app and handles sending/receiving messages across the Socket stream.

Is it correct that only one ServerSocket may bind to a Port? I take it there's no way to have a pool of objects accepting Socket connections?

I have two ideas for passing messages between ClientProxy objects. Either directly between ClientProxy objects that are "buddies" or via a central "Exchange" object, or better yet, pool of objects.

What are the Pros/Cons of the two approaches? Does the Exchange lend itself better to a distributed app?

Would the Observer and Mediator patterns, respectively, be appropriate?

Best Answer

Is it correct that only one ServerSocket may bind to a Port? I take it there's no way to have a pool of objects accepting Socket connections?

Correct. Only one thing can bind to a particular port on a given network interface at a time. Whenever a connection is received, a new socket is automatically created for the client on a deferred/internally-routed port. This is how a single listener can spawn any number of client handlers without waiting for the previous one to disconnect.

I have two ideas for passing messages between ClientProxy objects. Either directly between ClientProxy objects that are "buddies" or via a central "Exchange" object, or better yet, pool of objects.

You can have clients receive a proxy to their their buddies' message queues whenever the buddies come online. They can then directly queue messages to each other, avoiding the need of a centralized exchange. The server would keep a reference to all of its online clients and notify the interested parties of their friends' connections/disconnections via the queue.

Scaling this to fill a single box would become a matter of adding network interfaces (or using a port range on the one interface). Scaling this across multiple boxes would require server synchronization / passing queue proxies to-and-fro willy nilly.

Related Topic