Created
February 1, 2023 23:02
-
-
Save davidlares/9c039430ba5420456246834a0a19b03a to your computer and use it in GitHub Desktop.
Java multi-client chat PoC (from youtube video)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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