Replicate message to all chat customers

Asked

Viewed 475 times

1

I need to replicate a client’s message to everyone who’s connected except the client you sent. Below is the classes I have so far. How could I replicate these messages?

public class Servidor {
  public static final int porta = 4444;
  private ServerSocket serverSocket;

public static void main(String[] args) {
    try {
        new Servidor().iniciarServidor();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void iniciarServidor() throws IOException {
    serverSocket = new ServerSocket(porta);
    System.out.println("Servidor esperando conexões..");
    while (true) {
        Socket socket = serverSocket.accept();
        ThreadServidor st = new ThreadServidor(socket);
        st.start();
    }
}

}

public class Cliente {
private static Socket socket;
private Scanner scanner;

public static void main(String[] args) throws UnknownHostException, IOException {
    new Cliente().iniciarCliente();
}

public void iniciarCliente() throws UnknownHostException, IOException {
    System.out.println("Digite seu nome: ");
    scanner = new Scanner(System.in);
    String nome = scanner.nextLine();
    socket = new Socket("localhost", 4444);
    PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
    BufferedReader bf = new java.io.BufferedReader(new InputStreamReader(System.in));
    while (true) {
        String leitura = bf.readLine();
        pw.println(nome + ": " + leitura);
    }
}

}

public class ThreadServidor extends Thread {
private Socket socket;
PrintWriter printWriter = null;

public ThreadServidor(Socket socket) {
    this.socket = socket;
}

public void run() {
    try {
        String mensagem = null;
        BufferedReader bf = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        while ((mensagem = bf.readLine()) != null) {
            System.out.println("Mensagem do cliente: " + mensagem);
        }
        socket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}
  • What’s wrong with the code?

  • Nothing, just doesn’t send to all connected clients.

1 answer

0


Basically you need to store a list of client sockets and create a routine that iterates over all of them by writing to OutputStream of each.

Another alternative would be to create on the server threads written in addition to threads incoming.

I did a complete chat example using the second technique on which you can rely.

The important parts are below.

The first is the map with the message queues to be sent to each customer:

private final ConcurrentHashMap<String, BlockingDeque<Message>> users = new ConcurrentHashMap<>();

The map key is the user name and each value is a queue that stores messages to be sent to each client.

The class BlockingDeque is a special queue implementation where, if it is empty, the thread trying to read an item in the queue is waiting for an item to appear.

So, I create threads for each client who waits for the messages to be added in that queue and as soon as some of them arrive the thread writes to the client.

The thread code that sends the messages is this:

for (;;) {
    final Message message = outgoingMessagesToClient.take();
    ...
    outputStream.writeObject(message);
    outputStream.flush();
    ....
}

To send a message to all users, just add the message in all the queues, like this:

private void sendMessageForAll(final Message message) {
    users.values().stream().forEach(q -> q.add(message));
}

Note that I simplified the code here to avoid more complex details, such as the case where there is an outgoing chat message that terminates the connection. My suggestion is to implement gradually and then you start to insert more details,

Browser other questions tagged

You are not signed in. Login or sign up in order to post.