Implementation of chat lib and GUI
This commit is contained in:
parent
94307933d3
commit
c4779c1a06
13 changed files with 566 additions and 2 deletions
4
pom.xml
4
pom.xml
|
@ -5,7 +5,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>fr.univ-lyon1</groupId>
|
<groupId>fr.univ-lyon1</groupId>
|
||||||
<artifactId>Java TP</artifactId>
|
<artifactId>java-tp</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
<!-- Default configuration for running with: mvn clean javafx:run -->
|
<!-- Default configuration for running with: mvn clean javafx:run -->
|
||||||
<id>default-cli</id>
|
<id>default-cli</id>
|
||||||
<configuration>
|
<configuration>
|
||||||
<mainClass>fr.watteau.javafx_demo/fr.watteau.javafx_demo.HelloApplication</mainClass>
|
<mainClass>fr.univ.lyon1.gui.MainGui</mainClass>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
69
src/fr/univ/lyon1/client/Client.java
Normal file
69
src/fr/univ/lyon1/client/Client.java
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package fr.univ.lyon1.client;
|
||||||
|
|
||||||
|
import fr.univ.lyon1.common.Message;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class Client {
|
||||||
|
private final int port;
|
||||||
|
private final String address;
|
||||||
|
protected final Socket socket;
|
||||||
|
protected final ObjectOutputStream out;
|
||||||
|
private ObjectInputStream in;
|
||||||
|
protected boolean started = false;
|
||||||
|
|
||||||
|
public Client(String address, int port) throws IOException, InterruptedException {
|
||||||
|
this.address = address;
|
||||||
|
this.port = port;
|
||||||
|
socket = new Socket(address, port);
|
||||||
|
out = new ObjectOutputStream(socket.getOutputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnectedServer() throws IOException {
|
||||||
|
socket.close();
|
||||||
|
out.close();
|
||||||
|
if (in != null)
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String sendMessage(String content) {
|
||||||
|
Message msg = new Message(null, content);
|
||||||
|
|
||||||
|
try {
|
||||||
|
out.writeObject(msg);
|
||||||
|
out.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Fail to send message !");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Message messageReceived(Message msg) {
|
||||||
|
System.out.println();
|
||||||
|
System.out.println(msg);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() throws InterruptedException, IOException {
|
||||||
|
if (started)
|
||||||
|
return;
|
||||||
|
Thread clientSendThread = new Thread(new ClientSend(this, out, socket));
|
||||||
|
clientSendThread.start();
|
||||||
|
|
||||||
|
Thread clientReceiveThread = new Thread(new ClientReceive(this, socket));
|
||||||
|
clientReceiveThread.start();
|
||||||
|
|
||||||
|
started = true;
|
||||||
|
|
||||||
|
clientSendThread.join();
|
||||||
|
socket.close();
|
||||||
|
clientReceiveThread.interrupt();
|
||||||
|
}
|
||||||
|
}
|
61
src/fr/univ/lyon1/client/ClientReceive.java
Normal file
61
src/fr/univ/lyon1/client/ClientReceive.java
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package fr.univ.lyon1.client;
|
||||||
|
|
||||||
|
import fr.univ.lyon1.common.Message;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
|
||||||
|
public class ClientReceive implements Runnable {
|
||||||
|
private final Client client;
|
||||||
|
private ObjectInputStream in;
|
||||||
|
private final Socket socket;
|
||||||
|
|
||||||
|
public ClientReceive(Client client, Socket socket) {
|
||||||
|
this.client = client;
|
||||||
|
this.socket = socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
in = new ObjectInputStream(socket.getInputStream());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
Message msg;
|
||||||
|
try {
|
||||||
|
msg = (Message) in.readObject();
|
||||||
|
} catch (ClassNotFoundException|IOException e) {
|
||||||
|
if (e instanceof SocketException) {
|
||||||
|
System.err.println("Connexion closed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
System.err.println("Fail to read message object !");
|
||||||
|
e.printStackTrace();
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg == null)
|
||||||
|
break;
|
||||||
|
|
||||||
|
this.client.messageReceived(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.disconnectedServer();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Fail to disconnect !");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
src/fr/univ/lyon1/client/ClientSend.java
Normal file
31
src/fr/univ/lyon1/client/ClientSend.java
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package fr.univ.lyon1.client;
|
||||||
|
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class ClientSend implements Runnable {
|
||||||
|
private final Client client;
|
||||||
|
private final ObjectOutputStream out;
|
||||||
|
private final Socket socket;
|
||||||
|
|
||||||
|
public ClientSend(Client client, ObjectOutputStream out, Socket socket) {
|
||||||
|
this.client = client;
|
||||||
|
this.out = out;
|
||||||
|
this.socket = socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
Scanner sc = new Scanner(System.in);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
System.out.print(">> ");
|
||||||
|
String m = sc.nextLine();
|
||||||
|
|
||||||
|
if (m.equals("exit"))
|
||||||
|
break;
|
||||||
|
|
||||||
|
client.sendMessage(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
src/fr/univ/lyon1/client/MainClient.java
Normal file
26
src/fr/univ/lyon1/client/MainClient.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package fr.univ.lyon1.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MainClient {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
if (args.length != 2) {
|
||||||
|
printUsage();
|
||||||
|
} else {
|
||||||
|
String address = args[0];
|
||||||
|
int port = Integer.parseInt(args[1]);
|
||||||
|
Client c = new Client(address, port);
|
||||||
|
c.run();
|
||||||
|
}
|
||||||
|
} catch (IOException|InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printUsage() {
|
||||||
|
System.out.println("java client.Client <address> <port>");
|
||||||
|
System.out.println("\t<address>: server's ip address");
|
||||||
|
System.out.println("\t<port>: server's port");
|
||||||
|
}
|
||||||
|
}
|
31
src/fr/univ/lyon1/common/Message.java
Normal file
31
src/fr/univ/lyon1/common/Message.java
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package fr.univ.lyon1.common;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class Message implements Serializable {
|
||||||
|
private String sender;
|
||||||
|
private final String content;
|
||||||
|
|
||||||
|
|
||||||
|
public Message(String sender, String content) {
|
||||||
|
this.sender = sender;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSender(String sender) {
|
||||||
|
this.sender = sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSender() {
|
||||||
|
return sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return sender + ": " + content;
|
||||||
|
}
|
||||||
|
}
|
33
src/fr/univ/lyon1/gui/ClientGUI.java
Normal file
33
src/fr/univ/lyon1/gui/ClientGUI.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package fr.univ.lyon1.gui;
|
||||||
|
|
||||||
|
import fr.univ.lyon1.client.Client;
|
||||||
|
import fr.univ.lyon1.client.ClientReceive;
|
||||||
|
import fr.univ.lyon1.common.Message;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ClientGUI extends Client {
|
||||||
|
private final MainGui gui;
|
||||||
|
|
||||||
|
public ClientGUI(MainGui gui, String address, int port) throws IOException, InterruptedException {
|
||||||
|
super(address, port);
|
||||||
|
this.gui = gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message messageReceived(Message msg) {
|
||||||
|
gui.receiveMessage(msg.toString());
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (started)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Thread clientReceiveThread = new Thread(new ClientReceive(this, super.socket));
|
||||||
|
clientReceiveThread.start();
|
||||||
|
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
}
|
85
src/fr/univ/lyon1/gui/ClientPanel.java
Normal file
85
src/fr/univ/lyon1/gui/ClientPanel.java
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
package fr.univ.lyon1.gui;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.ScrollPane;
|
||||||
|
import javafx.scene.control.TextArea;
|
||||||
|
import javafx.scene.input.KeyCode;
|
||||||
|
import javafx.scene.input.KeyEvent;
|
||||||
|
import javafx.scene.text.Text;
|
||||||
|
import javafx.scene.text.TextFlow;
|
||||||
|
|
||||||
|
public class ClientPanel extends Parent {
|
||||||
|
private TextArea textToSend = new TextArea();
|
||||||
|
private ScrollPane scrollReceivedText = new ScrollPane();
|
||||||
|
private TextFlow receivedText = new TextFlow();
|
||||||
|
private Button sendBtn = new Button();
|
||||||
|
private Button clearBtn = new Button();
|
||||||
|
private final MainGui gui;
|
||||||
|
|
||||||
|
ClientPanel(MainGui gui) {
|
||||||
|
this.gui = gui;
|
||||||
|
scrollReceivedText.setLayoutX(20);
|
||||||
|
scrollReceivedText.setLayoutY(20);
|
||||||
|
scrollReceivedText.setPrefWidth(400);
|
||||||
|
scrollReceivedText.setPrefHeight(350);
|
||||||
|
scrollReceivedText.setContent(receivedText);
|
||||||
|
scrollReceivedText.vvalueProperty().bind(receivedText.heightProperty());
|
||||||
|
this.getChildren().add(scrollReceivedText);
|
||||||
|
|
||||||
|
sendBtn.setPrefWidth(80);
|
||||||
|
|
||||||
|
int btnMargin = 20;
|
||||||
|
|
||||||
|
textToSend.setLayoutX(scrollReceivedText.getLayoutX());
|
||||||
|
textToSend.setLayoutY(scrollReceivedText.getLayoutY() + scrollReceivedText.getPrefHeight() + 20);
|
||||||
|
textToSend.setPrefWidth(400-sendBtn.getPrefWidth()-btnMargin);
|
||||||
|
textToSend.setPrefHeight(100);
|
||||||
|
this.getChildren().add(textToSend);
|
||||||
|
textToSend.setOnKeyPressed(this::textToSendKeyPressed);
|
||||||
|
|
||||||
|
sendBtn.setText("Send");
|
||||||
|
sendBtn.setLayoutX(textToSend.getLayoutX() + textToSend.getPrefWidth() + btnMargin);
|
||||||
|
sendBtn.setLayoutY(textToSend.getLayoutY());
|
||||||
|
sendBtn.setPrefWidth(80);
|
||||||
|
sendBtn.setPrefHeight(40);
|
||||||
|
sendBtn.setVisible(true);
|
||||||
|
this.getChildren().add(sendBtn);
|
||||||
|
sendBtn.setOnAction(this::sendBtnAction);
|
||||||
|
|
||||||
|
clearBtn.setText("Clear");
|
||||||
|
clearBtn.setLayoutX(sendBtn.getLayoutX());
|
||||||
|
clearBtn.setPrefWidth(sendBtn.getPrefWidth());
|
||||||
|
clearBtn.setPrefHeight(sendBtn.getPrefHeight());
|
||||||
|
clearBtn.setLayoutY(textToSend.getLayoutY() + textToSend.getPrefHeight() - clearBtn.getPrefHeight());
|
||||||
|
clearBtn.setVisible(true);
|
||||||
|
this.getChildren().add(clearBtn);
|
||||||
|
clearBtn.setOnAction(this::clearBtnAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void send() {
|
||||||
|
String msg = textToSend.getText();
|
||||||
|
gui.sendMessage(msg);
|
||||||
|
textToSend.clear();
|
||||||
|
addMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendBtnAction(ActionEvent e) {
|
||||||
|
send();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void textToSendKeyPressed(KeyEvent e) {
|
||||||
|
if (e.getCode() == KeyCode.ENTER)
|
||||||
|
send();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearBtnAction(ActionEvent e) {
|
||||||
|
textToSend.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMessage(String message) {
|
||||||
|
Platform.runLater(() -> receivedText.getChildren().add(new Text(message+"\n")));
|
||||||
|
}
|
||||||
|
}
|
45
src/fr/univ/lyon1/gui/MainGui.java
Normal file
45
src/fr/univ/lyon1/gui/MainGui.java
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package fr.univ.lyon1.gui;
|
||||||
|
|
||||||
|
import javafx.application.Application;
|
||||||
|
import javafx.scene.Group;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MainGui extends Application {
|
||||||
|
private ClientPanel clientPanel;
|
||||||
|
private ClientGUI client;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Stage stage) throws Exception {
|
||||||
|
List<String> parameters = this.getParameters().getUnnamed();
|
||||||
|
client = new ClientGUI(this, parameters.get(0), Integer.parseInt(parameters.get(1)));
|
||||||
|
//ToDo: error management especially for bad server IP/port
|
||||||
|
//ToDo: Server IP/port enter by user on the GUI
|
||||||
|
|
||||||
|
stage.setTitle("Chat client");
|
||||||
|
stage.setWidth(440);
|
||||||
|
|
||||||
|
clientPanel = new ClientPanel(this);
|
||||||
|
Group root = new Group();
|
||||||
|
root.getChildren().add(clientPanel);
|
||||||
|
Scene scene = new Scene(root, 600, 500);
|
||||||
|
|
||||||
|
stage.setScene(scene);
|
||||||
|
stage.show();
|
||||||
|
client.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Application.launch(MainGui.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessage(String msg) {
|
||||||
|
client.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void receiveMessage(String msg) {
|
||||||
|
clientPanel.addMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
64
src/fr/univ/lyon1/server/ConnectedClient.java
Normal file
64
src/fr/univ/lyon1/server/ConnectedClient.java
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package fr.univ.lyon1.server;
|
||||||
|
|
||||||
|
import fr.univ.lyon1.common.Message;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class ConnectedClient implements Runnable {
|
||||||
|
private static int idCounter = 0;
|
||||||
|
private final int id = idCounter++;
|
||||||
|
private final Server server;
|
||||||
|
private final Socket socket;
|
||||||
|
private final ObjectOutputStream out;
|
||||||
|
private ObjectInputStream in;
|
||||||
|
|
||||||
|
ConnectedClient(Server server, Socket socket) throws IOException {
|
||||||
|
this.server = server;
|
||||||
|
this.socket = socket;
|
||||||
|
this.out = new ObjectOutputStream(socket.getOutputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Message sendMessage(Message message) throws IOException {
|
||||||
|
out.writeObject(message);
|
||||||
|
out.flush();
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
in = new ObjectInputStream(socket.getInputStream());
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
Message msg = (Message) in.readObject();
|
||||||
|
|
||||||
|
if (msg == null)
|
||||||
|
break;
|
||||||
|
|
||||||
|
msg.setSender(String.valueOf(id));
|
||||||
|
server.broadcastMessage(msg, id);
|
||||||
|
}
|
||||||
|
} catch (IOException | ClassNotFoundException e) {
|
||||||
|
if (!(e instanceof EOFException)) {
|
||||||
|
System.err.println("Client connection error");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
server.disconnectedClient(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeClient() throws IOException {
|
||||||
|
if (in != null)
|
||||||
|
in.close();
|
||||||
|
out.close();
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
31
src/fr/univ/lyon1/server/Connection.java
Normal file
31
src/fr/univ/lyon1/server/Connection.java
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package fr.univ.lyon1.server;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class Connection implements Runnable {
|
||||||
|
private final Server server;
|
||||||
|
private final ServerSocket serverSocket;
|
||||||
|
|
||||||
|
Connection(Server server) throws IOException {
|
||||||
|
this.server = server;
|
||||||
|
this.serverSocket = new ServerSocket(server.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
while (true) {
|
||||||
|
Socket clientSocket;
|
||||||
|
try {
|
||||||
|
clientSocket = serverSocket.accept();
|
||||||
|
ConnectedClient client = new ConnectedClient(server, clientSocket);
|
||||||
|
server.addClient(client);
|
||||||
|
Thread clientThread = new Thread(client);
|
||||||
|
clientThread.start();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Fail to connect the new client !");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
src/fr/univ/lyon1/server/MainServer.java
Normal file
23
src/fr/univ/lyon1/server/MainServer.java
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package fr.univ.lyon1.server;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MainServer {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
if (args.length != 1) {
|
||||||
|
printUsage();
|
||||||
|
} else {
|
||||||
|
int port = Integer.parseInt(args[0]);
|
||||||
|
new Server(port);
|
||||||
|
}
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printUsage() {
|
||||||
|
System.out.println("java server.Server <port>");
|
||||||
|
System.out.println("\t<port>: server's port");
|
||||||
|
}
|
||||||
|
}
|
65
src/fr/univ/lyon1/server/Server.java
Normal file
65
src/fr/univ/lyon1/server/Server.java
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package fr.univ.lyon1.server;
|
||||||
|
|
||||||
|
import fr.univ.lyon1.common.Message;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Server {
|
||||||
|
private final int port;
|
||||||
|
private List<ConnectedClient> clients = new ArrayList<>();
|
||||||
|
|
||||||
|
Server(int port) throws IOException {
|
||||||
|
this.port = port;
|
||||||
|
Thread connection = new Thread(new Connection(this));
|
||||||
|
connection.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectedClient addClient(ConnectedClient newClient) {
|
||||||
|
Message msg = new Message( "Server", newClient.getId() + " is connected !");
|
||||||
|
|
||||||
|
clients.add(newClient);
|
||||||
|
|
||||||
|
broadcastMessage(msg, -1);
|
||||||
|
|
||||||
|
System.out.println("Client "+newClient.getId()+" is connected !");
|
||||||
|
|
||||||
|
return newClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int broadcastMessage(Message message, int id) {
|
||||||
|
for (ConnectedClient client : clients) {
|
||||||
|
if (id == -1 || client.getId() != id)
|
||||||
|
try {
|
||||||
|
client.sendMessage(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Fail to send message to " + client.getId());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectedClient disconnectedClient(ConnectedClient client) {
|
||||||
|
try {
|
||||||
|
client.closeClient();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Fail to close client "+client.getId());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.remove(client);
|
||||||
|
|
||||||
|
Message msg = new Message("Server", "Client "+client.getId()+" is disconnected");
|
||||||
|
|
||||||
|
broadcastMessage(msg, -1);
|
||||||
|
|
||||||
|
System.out.println("Client "+client.getId()+" disconnected");
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue