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.
Related
I have some theoretical question regarding "message loops"; particularly returning result of operations happening in a message loop that runs in a different thread. I have the situation where I'm having a TCP server listening for incoming messages. For each incoming message the server will authenticate the client who sent the message and two things may happen:
If the authenticated client has an attached handler the received message will be passed to the handler's message queue.
If the client has no handler a new one will be created and the same as above (the message will be passed to its message queue).
The handler is currently an object implementing the Callable interface so that it'll run in a different thread and its simple enough the get the result of the operation. Now for my problem: Each handler can have N amount of messages to be processed. The handler has a "message loop" like functionality that runs until a timeout occurs - a timeout in this case would be the socket's idle time reaching a predefined treshold. What I would like to know, how can I get Java to return a value from within the message loop without actually terminating the thread. Something like the following:
while (true) {
if (expired(socket))
break; // the callable will finish the call() method.
// get the first item from the queue.
message = messageQueue.poll();
result = process(message);
// I want to return the result to the caller which is in a different thread.
}
Now obviously a return statement would stop the message loop and if the messageQueue contains more messages they'll be lost. Another naive approach would be to use a callback-like mechanism, which requires an extra object + I still need to synchronize the caller with the Callable in the background thread. Something like wait & notify although I have K threads running in the background.
What would be the sophisticated way to handle this situation of returning results of operations from within a message-loop in a different thread, without terminating the thread itself?
#Edit:
I'll give a description of the whole process so that it clarifies what is happening here.
A client sends a message (xml string) to the application through tcp sockets.
The application authenticates the client, and if the client has no associated handler it'll create one.
The app will push the message to the queue of the handler.
The handler runs in a separate thread waiting for incoming messages from clients they're associated with, they MUST NOT handle messages for other clients.
When the handler picks up a message it'll transform it into a SOAP message and will forward it to another system through TCP socket.
When the handler recieves the response it needs to delegate it back to the caller without terminating its message-loop.
So the caller is something like a Dispatcher dispatching messages to the threads that are running the handlers associated with the sender of the message. It also collects the response from the handlers and sends them back to the correct clients.
Each handler, currently has their own message queue where only those messages are pushed which the particular handle has to process. When a handler starts up, it'll open a TCP socket to the target system where they'll forward the incoming messages after transformations were applied. When the handler reaches the maximal allowed idle time (The socket were opened without sending a request) the socket will be closed and the message-loop stopped. At this point the handler will finish its execution. the purpose of this, is to have a socket for each individual clients through which they can send multiple requests without the need for the target system to do another authentication.
Few options/questions come to mind:
Is there a problem to terminate the thread, check the returned result and then re-submit this task to the same thread pool? You will get a result, analyze it, and then resubmit to the pool and continue the work
As this thread runs, it can submit the statuses to a different ("external") queue which is analyzed outside this thread. An independent thread always run and check this queue
That's as far as I could think on how to...
It depends on...
If you want to return simple type you can use a thead safe result queue (global or by caller).
Propably thread pool will be more suitable in your case.
I belive that the most universal way is callback mechanism.
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.
since hours I am thinking about how I should use Java Sockets to send and receive data. I hope you can help me finding a good way to do it.
I have build a Server/Client structure where the client connects to the server and gets his own thread handling a request-response method. The information are capsuled in XML.
At the beginning the Server starts a blocking socket read. First I use writeInt() where the lenght of the XML message is transmitted. After that the Server reads the amount of lenght bytes and parses the message. After the transmission the client goes in the receive state and waits for an response.
That is fine but after the client authenticates the server waits for the things that will come and blocks.
But what should I do when the server has no information which needs to be transmitted. I could try to destroy the read blocking and send the message to the client. But what happens if the client comens in mind that he has also a message and also begins to send. In that moment no one will listen.
For that maybe I could use some sort of buffer but I have the feeling that this is not the way I should go.
I have been searching for a while and found some interesting information but I didn't understand them well. Sadly my book is only about this simple socket model.
Maybe I should use two threads. One sending and one receiving. The server has a database where the messages are stored and waiting for transmission. So when the server receives a message he stores that message in the database and also the answer like "message received" would be stored in the database. The sender thread would look if there are new messages and would send "message received" to the client. That approach would not send the answer in millisenconds but I could image that it would work well.
I hope that I gave you enough information about what I am trying. What would you recommend me how to implement that communication?
Thanks
But what should I do when the server has now information which needs to be transmitted.
I would make writes from the server synchronized. This will allow you to respond to requests in one thread, but also send other messages as required by another thread. For the client you can have a separate thread doing the receiving.
A simpler model may be to have two sockets. One socket works as you do now and when you "login" a unique id is sent to the client. At this point the client opens a second connection with a dedicated thread for listening to asynchronous events. It passes the unique id so the server know which client the asynchronous messages are for.
This will give a you a simple synchronous pattern as you have now and a simple asynchronous pattern. The only downside is you have two socket connections and you have co-ordinate them.
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.
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.