This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I have found IBM 's whitepaper for "how must be simple client/server chat application".
Problem is: how must be architecture of more complex chat application with PROTOCOL like:
(-r <nick> <name> <pwd> // register new user)
(-s <nick> <pwd> // signin user)
(-q //quit from chat)
For example, I have code
ChatClient - start client
ClientThread - din/dout
ChatServer - start server
ServerThread - din/dout for every chat client
The more object oriented approach would be to define an interface or class, Command (extends / implements Serializable). These have one method for executing the command on the server. In pseudo code:
You construct command objects and send these using ObjectOutputStream and receive them using ObjectInputStream. The Command class / interface could have multiple sub classes, one for each command you want to support. For instance you could have a RegisterCommand, SignInCommand, QuitCommand, MessageCommand (for regular messages). You can then use a factory method for constructing commands from Strings:
The server then retrieves one command at a time, and invokes its execute method on the server. The command will then know what to do. In pseudo code:
As said in my first piece of code, execute probably needs a parameter of type ChatServer, as it will need to call a method on this: register(String, String, String), login(String, String), quit(), etc. An example:
There may be less intricate designs, but this is probably the easiest to extend with new commands. All you need to do is:
- add the necessary method to the ChatServer
- add another Command implementation that calls this method
- modify the CommandFactory to recognize this command
You can use a similar design for responses back to the client. Types of responses can be "nick already exists" (for registering), "login failed", or "succeeded". The easiest type of response is a simple enum, or even easier a String indicating only the response message.
The protocol then changes slightly. First of all, Command.execute gets a return type:
This is not much more than a simple ping-pong protocol: the client sends a command (or request) to the server, and the server sends back a response, until either one quits.
I have a threads synchronization problem but how to solve this problem i don't know.
Concrete problem is >>> server sends response before clientthread catches readObject()
and clientthread waits this response...
Your protocol is broken; the client will never send anything. Now I must admit, the requests (commands) and responses have different triggering mechanisms so it is a good thing to separate them, but the overall protocol must be as follows:
client: send request; receive response; repeat
server: receive request; send response; repeat
As your requests are sent as triggered by the GUI you cannot initiate anything without the GUI's help.
How I envision this:
Client GUI thread (Swing's Event Dispatcher Thread): gathers user input (notified by ActionListener or some other listener), sends a Command through the Socket to the client.
Client receiving thread (ClientThread): indeed wait forever until a stop response has been received. If the client is closed you can try to interrupt / terminate this thread. When a response is received notify the GUI thread (EventQueue.invokeLater).
Server thread (ServerThread): basically how you have it now; alternate in receiving, calculating the response, sending the response.
The GUI will still alternate between sending and receiving, only in two different threads. The order will be this:
1) Client GUI thread sends a command
2) Server thread receives the command
3) Server thread calculates the response
4) Server thread sends the response
5) Client thread receives the response
6) Client thread lets client GUI thread handle the response
Now the next command can be sent anywhere after step 1, but for each command sent this is the order of events, and because the server receives commands and sends responses in order of sending the client also receives responses in order, notifies the GUI thread in order and that one will handle them in order.