Skip to content

Instantly share code, notes, and snippets.

@davidlares
Created February 1, 2023 23:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidlares/9c039430ba5420456246834a0a19b03a to your computer and use it in GitHub Desktop.
Save davidlares/9c039430ba5420456246834a0a19b03a to your computer and use it in GitHub Desktop.
Java multi-client chat PoC (from youtube video)
import java.util.Scanner;
import java.net.Socket;
import java.io.*;
public class Client {
// elements
private Socket socket;
private BufferedReader bufferedReader;
private BufferedWriter bufferedWriter;
private String username;
// constructor
public Client(Socket socket, String username) {
try {
this.socket = socket;
this.bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
this.bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.username = username;
} catch(IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
}
}
// sending message to a client handler ()
public void sendMessage() {
try {
bufferedWriter.write(username);
bufferedWriter.newLine();
bufferedWriter.flush();
// grabbing test
Scanner scanner = new Scanner(System.in);
while(socket.isConnected()) {
String messageToSend = scanner.nextLine();
bufferedWriter.write("[" + username + "]: " + messageToSend);
bufferedWriter.newLine();
bufferedWriter.flush();
}
} catch(IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
}
}
// listening messages
public void listenForMessage() {
// creating a new Thread
new Thread(new Runnable() {
@Override
public void run() {
String messageFromGroupChat;
while(socket.isConnected()) {
try {
// reading
messageFromGroupChat = bufferedReader.readLine();
System.out.println(messageFromGroupChat);
} catch(IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
}
}
}
}).start();
}
public void closeEverything(Socket socket, BufferedReader bufferedReader, BufferedWriter bufferedWriter) {
try {
if(bufferedReader != null) {
bufferedReader.close();
}
if(bufferedWriter != null) {
bufferedWriter.close();
}
if(socket != null) {
socket.close();
}
} catch(IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.print("[PROGRAM] Enter your username: ");
String username = scanner.nextLine();
// creating the socket object
Socket socket = new Socket("localhost", 1234);
// client instance
Client client = new Client(socket, username);
client.listenForMessage();
client.sendMessage();
// last both messages are blocking messages
// since the rest is in different threads = they can running in a parallel mode
}
}
import java.util.ArrayList;
import java.net.Socket;
import java.io.*;
public class ClientHandler implements Runnable {
// static array of registered clients (this is responsible for sending messages to each participant)
public static ArrayList<ClientHandler> clientHandlers = new ArrayList<>();
// read data (messages)
private BufferedReader bufferedReader;
// write data (messages)
private BufferedWriter bufferedWriter;
// passed from the server class (establish the connection between Client-Server)
private Socket socket;
// name of the client
private String clientUsername;
// constructor
public ClientHandler(Socket socket) {
try {
this.socket = socket;
// setting up streams
this.bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // wrapping write
this.bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // wrapping read
// this is the name (it's sent as well)
this.clientUsername = bufferedReader.readLine();
// adding them into the ArrayList
clientHandlers.add(this);
// streaming
broadcastMessage("[SERVER]: " + clientUsername + " has entered the chat");
} catch(IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
}
}
// code executed in a thread
@Override
public void run() {
String messageFromClient;
while(socket.isConnected()) {
try {
// listen for messages
messageFromClient = bufferedReader.readLine();
broadcastMessage(messageFromClient);
} catch(IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
break;
}
}
}
public void broadcastMessage(String messageToSend) {
// looping the arrayList to broadcast a message
for(ClientHandler clientHandler: clientHandlers) {
try {
// checking for different users
if(!clientHandler.clientUsername.equals(clientUsername)) {
clientHandler.bufferedWriter.write(messageToSend); // send import junit.framework.TestCase;
clientHandler.bufferedWriter.newLine(); // done sending data
clientHandler.bufferedWriter.flush(); // buffer won't be sent out
}
} catch(IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
}
}
}
public void removeClientHandler() {
// removing client from the arrayList
clientHandlers.remove(this);
// then, we broadcast
broadcastMessage("[SERVER]: " + clientUsername + " has left the chat");
}
public void closeEverything(Socket socket, BufferedReader bufferedReader, BufferedWriter bufferedWriter) {
removeClientHandler();
try {
if(bufferedReader != null) {
bufferedReader.close();
}
if(bufferedWriter != null) {
bufferedWriter.close();
}
if(socket != null) {
socket.close();
}
} catch(IOException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.net.*;
public class Server {
// instance
private ServerSocket serverSocket;
// constructor
public Server(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
}
// starting server
public void startServer() {
try {
while(!serverSocket.isClosed()) {
// waiting for a client to connect
Socket socket = serverSocket.accept(); // this is a blocking method (store it in a Thread)
System.out.println("A new client has connected");
// using a handler
ClientHandler clientHandler = new ClientHandler(socket); // this implements the runnable (instance executed in a Thread)
// thread instance and execution
Thread thread = new Thread(clientHandler);
thread.start();
}
} catch(IOException e) {
//
}
}
public void closeServerSocket() {
try {
if(serverSocket != null) {
serverSocket.close();
}
} catch(IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
// this server instance creates a client (on the specified port)
ServerSocket serverSocket = new ServerSocket(1234);
Server server = new Server(serverSocket);
server.startServer(); // starting the server
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment