"Hi, Amigo!"
"Hello, Captain Squirrels, sir!"
"We need an alternative communication channel in the event of a natural disaster."
"Is there something you're not telling me? What natural disaster?"
"Unlike civilians, we must always have a backup communication channel."
"Skype?"
"It's not very reliable, and we don't have control over their servers. We'll write a chat client with its own blackjack... I mean, with its own server and clients!"
"And will it have a graphical interface?"
"If you do exactly what Agent IntelliJ IDEA tells you to do, then there will be a graphical interface."
"Wow, finally! Can I ask another question?"
"Too many questions. As a bonus exercise, you can write a bot to answer your own questions. "Move out!"
"Yes, sir!"
8
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 1)
Today we're going to write a chat system: A set of programs that you can use
to exchange text messages. The system will consist of one server and
multiple clients, one for each chat participant.
Let's start with the server. We'll need the following classes:
1) Server - The server's main class.
14
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 2)
First of all, for convenience in working with the console, we'll implement the ConsoleHelper class. In
the future, any work with the console should happen through this class.
Add the following to it:
1) A static BufferedReader field initialized using System.in.
8
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 3)
Before moving on, we need to work out the protocol for communication between the client and server.
Let's outline the main aspects of the protocol: When a new client wants to connect to the server, the server should request the client name.
8
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 4)
A Message is data that one party sends and the other receives.
Each message must have a MessageType and some additional data,
for example, a text message must contain text.
Since the messages will be created in one program and read in another.
28
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 5)
The client and server will communicate through a socket connection.
One side will write data to the socket, while the other will read. They interact by exchanging Messages.
The Connection class will wrap the java.net.Socket class.
28
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 6)
Let's move on to the most important part: writing the Server class.
The server must support multiple simultaneous connections with different clients.
This can be done using the following algorithm:
- The server creates a server socket connection.
14
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 7)
Because the server can work with multiple clients simultaneously, we're going to need
a method to send a message to everyone all at once.
Add the following to the Server class:
1) A static Map<String, Connection> connectionMap field, where the key is the client name.
28
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 8)
The Handler class must implement the client communication protocol.
Let's identify independent stages of the protocol and implement them in separate methods:
The first stage is the handshake (in which the server meets the client).
14
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 9)
The second stage, which is no less important, is sending information to the client (new participant) about the
other clients (chat participants).
14
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 10)
The third stage is the server's main message-processing loop.
Add a private void serverMainLoop(Connection connection, String userName) throws IOException, ClassNotFoundException
method, where the meaning of the parameters is the same as in the notifyUsers() method.
28
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 11)
It's time to write the main method of the Handler class, which will call all
the helper methods we wrote earlier. Implement the void run() method in the Handler class.
14
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 12)
Let's start writing the client. When the client starts running, it should request the server address and server port,
connect to the specified address, receive a name request from the server, ask the user for his or her name,
send the username to the server.
14
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 13)
Let's continue to implement helper methods in the Client class.
Add the followings methods, which will be available to subclasses,
but not to other classes outside the package:
1) String getServerAddress() - It should ask the user to enter the server address,
and return the entered value.
28
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 14)
Let's start writing the main functionality of the Client class.
1) Add a public void run() method. It should create a helper SocketThread, wait until it establishes a connection with the server, and then in a loop, read messages from the console and send them to the server.
14
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 15)
Let's write the implementation of the SocketThread class. We'll start with simple helper methods.
Add methods that will be available to subclasses but not accessible to other
classes outside the package:
1) void processIncomingMessage(String message) - It should display the message on the console.
28
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 16)
Now everything is ready for us to add the necessary methods to the SocketThread class.
1) Add a protected clientHandshake() throws IOException, ClassNotFoundException method.
This method will represent the client to the server. It must:
a) In a loop, use the connection field to receive messages.
8
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 17)
The last, but most important, method of the SocketThread class is the void run() method. Add it.
Given the methods we've already created, implementing this method looks very simple.
Let's do it:
1) Request the server address and server port using the getServerAddress() and getServerPort() methods.
14
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 18)
Sometimes you can't find someone worth talking to. Don't start talking to yourself :).
Let's write a bot that will be a client that automatically respond to certain commands.
The easiest version would be a bot that sends the current time or date when someone asks for it.
28
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 19)
Now we'll implement the BotSocketThread class, or rather we'll override some
methods. All of its main functionality is inherited from SocketThread.
1) Override the clientMainLoop() method.
14
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 20)
We've already implemented a console-based client and a chat bot. Why not a client with a GUI?
It will also work with our server, but it will have a graphic window, buttons, etc.
Well, let's get started. The Model-View-Controller (MVC) pattern is well suited for a GUI-based client.
28
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 21)
I have great news for you. The view component is already done. I've added a ClientGuiView class.
It uses the javax.swing library. You should really study every line of this class.
If everything is clear, that's wonderful.
8
Task
Java Multithreading,
level 6,
lesson 15
Locked
Chat (part 22)
So let's recap:
• You wrote a text messaging server.
• You wrote a console-based client that can connect to the server and exchange messages with other chat participants.
• You wrote a bot client that can receive requests and send information about the current date and time.
GO TO FULL VERSION