Java multithreaded stateful server - networking design - java

I'm trying to implement a stateful, multi-client server application and have some questions about the networking/threading design. The problem I'm currently facing is how to exchange messages between the communication layer and the logic layer.
The server handles multiple clients, where each of them can be active in multiple "channels", where each channel has multiple stages and may have multiple clients acting in it. Think of it to something similar as a chat program with multiple rooms.
I have already implemented the receiving of messages on the server side. Each client has his own thread that blockingly reads the data and decodes into a message. Now how to proceed? In my oppinion, each channel should also have this own thread to easily maintain its state. I could use a BlockingQueue to exchange the received messages with the channel thread, who's blockingly waiting for new messages on that queue.
But then how to send messages to the clients? The logic in the channel will handle the message, and produce some messages to be sent to one/some/all of the clients. Is it safe to use the channel thread to directly write to the socket? Or should I use another BlockingQueue to transmit the messages to the client handler thread? But how to wake it then, since it's waiting on the socket to read? Or should I use a separate send-thread per client, or even a separate send-socket?
BTW: I know I could use existing libraries for the networking layer, but I want do do it from scratch on plain sockets.

Put a send message method on the communication object that wraps the socket. Synchronize this method so that only one thread can be calling it at once. Then, it doesn't make any difference how many threads call this method. Each message will only be sent one at a time. You also don't have to disturb the thread that's blocking to read. This send method will be a quick enough operation that you don't have to worry about other threads blocking while a thread sends.
As long as the channel has a reference to the communication objects for each connected client, it can send messages and not worry about it.
If it ever caused problems, you could always modify that send message to enqueue the object to be sent. Then you could have a specific send thread to block on the queue and write the contents to the socket. But from my experience, this won't be necessary.

What about a event mechanism? When you ready with processing the request and there is a data for client available, then simply send it with an event for the client socket handler thread. as because the transmission from client is ended, you can send reply normally - if i think correctly.

Related

Understanding of Netty internals

In my understanding of Netty's, incoming message passed to eventLoop(only one eventLoop, one thread). Next, EventLoop doesn't process it, but pass it to ExecutorService(it holds multiple threads in pool) for execution.
All this happens with the help of NIO. EventLoop waits for incoming messages and pass it by selectors, keys, channels etc.
Am I right?
Netty 4 is used
As far as i know Netty uses the EvenLoopGroups for handeling incoming and outgoing data as well as incoming connections.
That shouln't be so interesting when you start using Netty as the way the data goes through different classes. When a message is inbound the first interfacce you can intercept it is the decoder (ByteToMessageDecoder) where your encrypted ByteBuf is available. Then its making its way through the handler (ChannelInboundHandler).

Displaying the command prompt? [duplicate]

I want to write a chat application in Java using Swing as an interface.
I have come up with an idea (with the help of MadProgrammer), but I am not sure whether it is the best way to go about this.
There are two Blockinqueue queues in the main Thread, one for incoming messages and one for outgoing messages.
There are four threads, two for outgoing and two for incoming messages, one each to handle the GUI and the socket.
Threads for outgoing messages:
ActionListener (Swing): Is triggered when user clicks "send" in GUI. The thread adds the new message to the Outgoing Queue and triggers notifyAll() on it.
socketOutgoing: Has access to socket. Sleeps, with wait() on Outgoing Queue, until it is notified. Sends new messages in Outgoing Queue through socket, then goes back to sleep again.
Threads for incoming messages:
socketIncoming: Has access to socket. Checks continuously for new
message in socket (how?). When there is a new message, adds it to
the Outgoing Queue and triggers notifyAll() on it.
Swingworker displayIncoming: Sleeps, with wait() on Incoming Queue, until it is notified. Displays new messages in GUI, then goes back to sleep again.
While this would theoretically work, it seems a bit messy (and unreliable) to have four threads for this.
Is there a more practical solution?
Note to future readers: My description of socketIncoming was misguided: It is not possible to "check continuously for new message in socket".
When you call ObjectInputStream#readObject(), and there is no new message, it simply waits, or "blocks", until a new messages arrives. There is no way to check beforehand whether a new message has arrived. See this question.
If I was thinking about doing something like I would probably set up two queues, an outgoing and incoming queue. These would be used to "stage" messages.
The idea being that outgoing messages would be placed into the outgoing queue and when Thread was able to, it would pop off the next message and send it. When the queue was empty, it would simply "wait" until a new message become available.
The concept would work in reverse for the incoming queue. The Thread would read a message and push it onto the incoming queue.
Some other process (possibly a SwingWorker) would be monitoring the queue and pop the next message of it and re-sync it with the GUI.
You might find Concurrency in Swing of some use.
How the underlying protocol actually worked would dictate a lot more of the details though
for a simple chat application you shall have two parts
Client part
Server part.
Now, you have to decide which protocol you want to use for your communication [Tcp] or [Udp]. Though your message transmission should be reliable so you have to use java Tcp ServerSocket. your server will be multi-threaded means for each client connect with server will have separate thread to handle all message communication from that client.
For Client side, it will have GUI componenet and one dedicated thread to receive message from server. when you want to send message to any user, just pass the message and send through client socket.

Multiple Threads Sharing One Socket

I have a scenario where multiple threads need to communicate with external system on one socket. Each thread's message can be identified by a unique id.
In this scenario where all threads share same socket, can I use blockQueues. Since the threads can produce request and consume response, can i have singleton component say "Socketer" who holds the socket and have two BlockQueues (incoming & outgoing). Any message on outgoing queue is written on socket and any message from socket is sent to incoming queue. The socketer also maintains the hashtable of all the producer threads and as it reads response, it identifies the corresponding producer and hands over response to it.s
Please suggest if it is a right design approach or advise the improvement. My threads are actually WebServices and I am in Spring environment.
Thanks
I don't see why you need the hash table, but you do need a response queue per thread. You could embed the correct response queue into the request message.
But are you sure you can't open multiple connections to the external system? It would make your life a lot simpler.

Java chat application using Swing (Conceptual)

I want to write a chat application in Java using Swing as an interface.
I have come up with an idea (with the help of MadProgrammer), but I am not sure whether it is the best way to go about this.
There are two Blockinqueue queues in the main Thread, one for incoming messages and one for outgoing messages.
There are four threads, two for outgoing and two for incoming messages, one each to handle the GUI and the socket.
Threads for outgoing messages:
ActionListener (Swing): Is triggered when user clicks "send" in GUI. The thread adds the new message to the Outgoing Queue and triggers notifyAll() on it.
socketOutgoing: Has access to socket. Sleeps, with wait() on Outgoing Queue, until it is notified. Sends new messages in Outgoing Queue through socket, then goes back to sleep again.
Threads for incoming messages:
socketIncoming: Has access to socket. Checks continuously for new
message in socket (how?). When there is a new message, adds it to
the Outgoing Queue and triggers notifyAll() on it.
Swingworker displayIncoming: Sleeps, with wait() on Incoming Queue, until it is notified. Displays new messages in GUI, then goes back to sleep again.
While this would theoretically work, it seems a bit messy (and unreliable) to have four threads for this.
Is there a more practical solution?
Note to future readers: My description of socketIncoming was misguided: It is not possible to "check continuously for new message in socket".
When you call ObjectInputStream#readObject(), and there is no new message, it simply waits, or "blocks", until a new messages arrives. There is no way to check beforehand whether a new message has arrived. See this question.
If I was thinking about doing something like I would probably set up two queues, an outgoing and incoming queue. These would be used to "stage" messages.
The idea being that outgoing messages would be placed into the outgoing queue and when Thread was able to, it would pop off the next message and send it. When the queue was empty, it would simply "wait" until a new message become available.
The concept would work in reverse for the incoming queue. The Thread would read a message and push it onto the incoming queue.
Some other process (possibly a SwingWorker) would be monitoring the queue and pop the next message of it and re-sync it with the GUI.
You might find Concurrency in Swing of some use.
How the underlying protocol actually worked would dictate a lot more of the details though
for a simple chat application you shall have two parts
Client part
Server part.
Now, you have to decide which protocol you want to use for your communication [Tcp] or [Udp]. Though your message transmission should be reliable so you have to use java Tcp ServerSocket. your server will be multi-threaded means for each client connect with server will have separate thread to handle all message communication from that client.
For Client side, it will have GUI componenet and one dedicated thread to receive message from server. when you want to send message to any user, just pass the message and send through client socket.

Java sockets event driven

I have a client that will connect to a server through a socket. After connecting every event that happens on the server will be sent to all registered clients.
Every client should receive data related to the event.
I just need to implement the client...meaning I need to connect to the server and receive the events' data.
I was thinking on doing something like:
this.socket = new Socket(InetAddress.getByName(host),
this.socket.connect(socket.getLocalSocketAddress(), SOCKET_TIMEOUT);
And then launch a thread which gets the InputStream of the socket in a while loop.
But I don't know if this the best way to implement an event driven client through a socket.
Is it?
In an event driven environment a Datagram Socket will incur lower network overhead but will not give you the reliability. Here is a tutorial about writing datagram socket clients and servers.
This is often done by spawning a separate thread for the client that continuously makes blocking calls to read() from the stream - that way, as soon as data becomes available the read() call unblocks and can act on what it received ('the event fires'), then it goes back to blocking waiting for the next event.
You don't necessarily need a thread here unless the client has to respond to some other input like GUI events.
Then, assuming you are talking about TCP, read from the socket in a loop, buffering received data until you have a complete application "event", and call your application "event handler". It's that simple.

Categories

Resources