We will use the previous tutorial to write a Chat application.
This application allow a client to communicate with all the other clients connected to the server.
The communication is done by implementing a specific protocol between the
server and clients. This is used to decode data received and encode datas to
send.
Threads are also used for doing action
automatically like reading input datas.
The basis of client/server was seen in Tutorial 1.
In the previous tutorial, a client can send datas only to the server.
In a chat application, the client could send datas to anyone connected.
To send datas from a client to another, the datas can goes directly from one
client to the other.
Another way is to send datas to the chat server and inform him that datas are
for a particular client. We will use the second way for this chat tutorial :
Transmission of a message
The advantage of this is that the client have a single
connection (to the server) and can talk with multiple clients. Moreover, the
server don't transmit the IP of a client to another one (security).
All clients have to connect themself to the server.
The server should listen for client connection.
For this, acceptConnection is called in loop
in a thread (this method blocks until a connection is made).
Accept client connections |
acceptClientsThread = new Thread() { |
ChatServerLink class extends ServerLink
used in previous tutorial for storing client pseudo, client authentification and
a thread used to listen for datas received (this thread will be used later in
this tutorial).
ChatServerLink |
public class ChatServerLink extends ServerLink |
To interpret data flow, datas should be encoded in a language
understandable by the server and the client.
By using the same language for the client and the server, the sender is sure that
his datas sended are well processed by the receiver.
For example, a client can send an instruction (to the server) to transmit some datas to another.
Before implementing the language used by the chat application,
we have to know which instructions will be transmitted from a client to another
or towards the server.
This chat application will works like this :
A client must authentify him, to the server, by sending his pseudo. Pseudo is unique.
A client not identified can't use the chat service until he his authentified.
The server send the list of clients authentified to each client authentified.
A client can send a text message to any client authentified.
The server can disconnect any client he wants and send any information to any clients he wants.
We have to encode original instruction to a
succession of bytes/characters. Datas encoded could be decoded to extract the
original instruction.
Datas will be encoded using tags :
<TAG>value</TAG>
TAG is a reserved word associated to an
instruction.
value is the value of the instruction.
Tag used to implement the language are (in
ProtocolEnums):
REQUEST : request a pseudo or a disconnection.
MESSAGE : text message from a client to another
PSEUDO : authentification of a client to the server.
PSEUDO_LIST : contains pseudo list of client authentified
INFO : Information message from the server (will be opened in a dialog box).
To send a message from a client (Pseudo1) to another
(Pseudo2), the client will encode his message like this :
<MESSAGE><FROM>Pseudo1</FROM><TO>Pseudo2</TO><BODY>Text</BODY></MESSAGE>
When the server will receive this message, by parsing the datas, he will fing
the tag MESSAGE. Value of this tag is <FROM>Pseudo1</FROM><TO>Pseudo2</TO><BODY>Text</BODY>.
He already know which client is the sender (because he receive the datas from
him), by parsing this value he will find the addressee and the text to send
him.
Encoding and decoding are done in Encoder/Decoder
classes.
First thing is to listen if some datas are received. For this,
we will use a thread that check in loop if some datas can be readed.
When some datas can be readed, with process them in
processInput by implementing the Protocol
interface.
Receiving thread |
//Listen for datas received |
Now, we have to implement our language with the
Protocol interface and attach it to our connection with
connection.setProtocol(protocol)
Protocol |
public interface Protocol |
The implementation is different for the server and the
client. For example, the server ask for authentification and the client answer
the request.
Here is how datas are processed by a client (in
Client).
First, he read the datas into a String. Then, he parse the datas as a vector
containing tags and their corresponding values. Finally, depending on tag
received, we do what should be done.
Client side |
public void processInput(InputStream in) |
Now, how datas are processed by the Server (in
Server).
The server manage authorizations. He blocks datas from client not authentified.
Server side |
public void processInput(InputStream in) |
I've just explain interesting part ie new 'Network' part of
this tutorial.
A lot of code is for the GUI (not explained here).
In package Network.Chat :
IntroFrame : first frame,
display author informations and ask if you are the server or a client.
SettingsFrame :
second frame, ask informations like your pseudo, IP and communication port.
IpPanel :
used by SettingsFrame to enter an IP address.
ChatFrame
: GUI.
Server
: code for the server.
Client : code for the client.
In package Network.Chat.Protocol :
Encoder : Encode datas
Decoder : Decode datas.
ProtocolEnums : contains tag of the
communication language.
ChatServerLink :
extends ServerLink to store user properties.
Hope that you like this tutorial !
Instead of defining a communication language like we have doing here, you can use RMI (Remote Method Invocation) for doing the same job.
RMI allows you to invokes methods on an object running in another JVM (Java Virtual Machine).
That is to say, for examples, two differents Java applications.
The chat server runs here in a GUI. Generally, the server have no GUI an
runs without human intervention.
Clients register themself to the chat server and have a pseudo/login. They
log themself by sending their pseudo/login to the server.
In this tutorial, like the previous, we have only seen how to send text (characters).
But, we can send files, pictures ...
This will be done in Tutorial 3, a basic HTTP
server.
I've run a server and 2 clients (you can connect all clients you wants). These 3 applications runs independently.
I've runs them in the same computer for these screen shots, but they can be
executed under differents computers and differents OS.
Here are what the two clients sees :
Clients applications
Here is the server application :
The server application
Last modified on 01/07/2010 | |
Copyright © 2004-2010 Jérôme JOUVIE - All rights reserved. | http://jerome.jouvie.free.fr/ |