Based on the RabbitMQ library, the chat consists in one server application, and another for clients (i.e. the server application should be launched on a host, before the clients can launch their one). Based on the publish-subscribe pattern, everyone follows everyone. However, our chat is centralized.
-
Each client can connect/disconnect whenever they want without leaving the application.
-
A real-time connected user list is proposed (even for those not connected).
-
On its connection, the client will receive all the message history.
-
Server logs indicate connections/disconnections/errors.
-
The server will load messages from last sessions on launch, and will save them all on exit (by using the file
$HOME/.superchat/history2
on the host).
-
The
Connection
andMessage
classes:-
Serializable classes transmitted between clients and also the server.
-
The first one contains information about the connection and disconnection requests, and the second about the content, sender and time of the message.
-
-
The
Client
class/interface:-
Created in the
Application
and bound with it. -
Saves her/his pseudo on the server side by using the a
RPC
pattern (i.e. a request queue is created to sendConnection
requests to theServer
, and a temporary response queue is created on theClient
side to inform her/his that the request was accepted or denied). -
On
Connection
successful, theServer
also gives the connected pseudos and message history to this new user, by using the sameRPC
pattern/queue (i.e. on thisRPC
the boolean response, and these two lists, are published by theServer
in the response queue, and retrieved by theClient
with aBlockingQueue
). -
Disconnects her/his by publishing a
Disconnection
request in the same request queue that theConnection
ones use. However, no response from theServer
is expected (i.e. this is not aRPC
call). -
Subscribes to all the other
Clients
to receive theirMessages
and publishes to all their timelines when sending. To do that afanout
exchange is created.
-
-
The
Application
class:-
The GUI bound with a
Client
; the one launched by a user. -
Informs the
Client
of the user's inputs so that it can act on them.
-
-
The
Server
class:-
Accepts or denies
Connection
requests (using the previously describedRPC
pattern), and executes theDisconnection
ones by updating a list of unique pseudos. -
Spreads the
Connection
andDisconnection
to all the clients, when they are confirmed, using afanout
exchange. -
Also receives
Messages
from theClients
to retrieves/saves the message history on launch/exit, in the$HOME/.superchat/history2
file on theServer
host.
-
Here the summary of the exchanges (using RabbitMQ
) between the Client
and Server
entities:
-
The implementation was much simpler and faster, by the ease of implementing patterns.
-
The number of lines of code (used only for chat management, not the graphical interface) seems to be lower.
From these observations, the library was more appropriate for this kind of application. The desired patterns was easy to implement, and in addition remote procedure calls could also be used quite easily if needed.
-
For security issues, the URI associated to the queues/exchanges could be improved, and each pseudo associated to a password (to avoid identity theft).
-
For backup issues, the message history file should not be stored on the host, but on the client side. We could also save the message history every X minutes or every Y messages to avoid loosing them on a power cut for example.
-
For performance and security issues, limitations and management should be added (maximum number of clients, maximum length of messages, etc.), depending on the host. Also, recovery algorithms should be optimized.
-
For ethical issues, the chat itself should not be used this way, because it implies a centralization of user data (names, messages, and metadata). Since we have already implemented a publish-subscribe traffic model, we could make this chat completely decentralized.
-
From the previous observations, we could use the concept of master node, and use a connected client as the server. On her/his disconnection, we could use an election algorithm to hand over the responsibilities to another node which would be the new master node. Our chat would be totally decentralized.
-
We could also improve the previous concept by using multiple master nodes, mainly for security issues (but also for performances).
-
First you need to install RabbitMQ on your computer:
user:~/Java-RabbitMQ-Chat/ $ sudo apt install rabbitmq-server
You may also need to launch the server using the
sudo rabbitmq-server
command. -
Next you need first to start the
Server
. To do this you have to execute the following command:-
If you are trying to launch the
Server
onlocalhost
:user:~/Java-RabbitMQ-Chat/ $ mvn compile exec:java -Dexec.mainClass=superchat.Server
-
Otherwise, if you want to launch it on
<host>
:user:~/Java-RabbitMQ-Chat/ $ mvn compile exec:java -Dexec.mainClass=superchat.Server -Dexec.args=<host>
-
-
Then to start a user connection:
user:~/Java-RabbitMQ-Chat/ $ mvn compile exec:java -Dexec.mainClass=superchat.Application
If you aren't using
localhost
, as said previously, you should also use-Dexec.args=<host>
.
-
When executing
Server
:Error: java.net.ConnectException: Connexion refusée
You may need to start the RabbitMQ server with the
sudo rabbitmq-server
command. -
When executing
Application
:Exception in thread "main" java.awt.AWTError: Can't connect to \<X server\> using \<IP address:x.x\> as the value of the DISPLAY variable.
You may need to execute the
export DISPLAY=:0
command.