Servidor de chat com mensagens privadas

6 respostas
bigodines

Olá pessoal, primeiro, desculpa se isso não é Java Avançado (moderadores por favor movam para o forum ao qual minha dúvida for mais apropriada)

Não tenho experiência com programação java (estou vindo do PHP e C) E desenvolvi (juntamente com um professor meu) um servidor e um cliente simplesinho de chat que suporta multiplos usuários. Funciona BELEZA.

Só estou querendo acrescentar um recurso a ele: A possibilidade de conversa reservada, ou seja, uma função em que eu diga a qual conexão deverá ser enviada a mensagem. ALguém pode me ajudar?

Bom, segue o código do meu servidor (por favor não riam):

// ServidorChat.java
import java.io.*;
import java.net.*;
import java.util.*;
public class ServidorChat extends Thread {
   public static void main(String args[]) {
     // instancia o vetor de clientes conectados
     clientes = new Vector();
     try {
        // criando um socket que fica escutando a porta 2222.
        ServerSocket s = new ServerSocket(2222);
        // Loop principal.
        while (true) {
          // aguarda algum cliente se conectar. A execução do
          // servidor fica bloqueada na chamada do método accept da
          // classe ServerSocket. Quando algum cliente se conectar
          // ao servidor, o método desbloqueia e retorna com um
          // objeto da classe Socket, que é porta da comunicação.
          System.out.print("Esperando alguem se conectar...");
          Socket conexao = s.accept();
          System.out.println(" Conectou!");
          // cria uma nova thread para tratar essa conexão
          Thread t = new ServidorChat(conexao);
          t.start();
          // voltando ao loop, esperando mais alguém se conectar.
        }
     }
     catch (IOException e) {
        // caso ocorra alguma excessão de E/S, mostre qual foi.
        System.out.println("IOException: " + e);
     }
  }

  // Parte que controla as conexões por meio de threads.
  // Note que a instanciação está no main.
  private static Vector clientes;

  // socket deste cliente
  private Socket conexao;

  // nome deste cliente
  private String meuNome;

  // construtor que recebe o socket deste cliente
  public ServidorChat(Socket s) {
    conexao = s;
  }

  // execução da thread
  public void run() {
    try {
      // objetos que permitem controlar fluxo de comunicação
      BufferedReader entrada = new BufferedReader(new InputStreamReader(conexao.getInputStream()));
      PrintStream saida = new PrintStream(conexao.getOutputStream());
      // primeiramente, espera-se pelo nome do cliente
      meuNome = entrada.readLine();
      System.out.println("Entrou usário: " + meuNome); 
      // agora, verifica se string recebida é valida, pois
      // sem a conexão foi interrompida, a string é null.
      // Se isso ocorrer, deve-se terminar a execução.
      if (meuNome == null) {return;}
      // Uma vez que se tem um cliente conectado e conhecido,
      // coloca-se fluxo de saída para esse cliente no vetor de
      // clientes conectados.
      clientes.add(saida);
      // clientes é objeto compartilhado por várias threads!
      // De acordo com o manual da API, os métodos são
      // sincronizados. Portanto, não há problemas de acessos
      // simultâneos.
      // Loop principal: esperando por alguma string do cliente.
      // Quando recebe, envia a todos os conectados até que o
      // cliente envie linha em branco.
      // Verificar se linha é null (conexão interrompida)
      // Se não for nula, pode-se compará-la com métodos string
      String linha = entrada.readLine();
      while (linha != null && !(linha.trim().equals(""))) {
        // reenvia a linha para todos os clientes conectados
        sendToAll(saida, " disse: ", linha);
        // espera por uma nova linha.
        linha = entrada.readLine();
      }
      // Uma vez que o cliente enviou linha em branco, retira-se
      // fluxo de saída do vetor de clientes e fecha-se conexão.
      sendToAll(saida, " saiu ", "do chat!");
      clientes.remove(saida);
      conexao.close();
    }
    catch (IOException e) {
      // Caso ocorra alguma excessão de E/S, mostre qual foi.
      System.out.println("IOException: " + e);
    }
  }
  // enviar uma mensagem para todos, menos para o próprio
  public void sendToAll(PrintStream saida, String acao, String linha) throws IOException {
    Enumeration e = clientes.elements();
    while (e.hasMoreElements()) {
      // obtém o fluxo de saída de um dos clientes
      PrintStream chat = (PrintStream) e.nextElement();
      // envia para todos, menos para o próprio usuário
      if (chat != saida) {chat.println(meuNome + acao + linha);}
    }
  }
}

Abraços.

6 Respostas

saoj

Doido,

Nem li o seu código, mas em qualquer aplicação client/server vc tem sendToAll e sendToOne.

(Ok vou ler o seu código)

Cara vc precisa de um protocolo de comunicacão e de um sendToOne.

O seu servidor não tem protocolo, apenas faz broadcast das mensagens.

Um protocolo básico:

SAY#Um abraço
PRIVATE#Sergio#Sergio isso está no reservado
BYE#Sergio

Good luck !!!

A

Cara teria como você postar a versão do cliente…

kartler

O GUJ Tem algo parecido…acho que daria pra vc dá uma olhada no código também… e poder até melhorar .

bigodines

Certo. obrigado a todos pelas respostas rápidas.

Por acaso alguém tem o link ou o nome do artigo no GUJ pra eu dar uma procurada? Obrigado.

_fs

www.guj.com.br

:smiley:

http://www.guj.com.br/java.artigo.20.1.guj

bigodines

Valeu lipe.

Criado 6 de outubro de 2004
Ultima resposta 7 de out. de 2004
Respostas 6
Participantes 5