Chat multi usuários com Socket e Interface Swing

Neste post irei disponibilizar uma vídeo aula divida em 10 partes de aproximadamente 15 minutos cada parte, onde demonstro um forma de construir um chat multi usuários com socket e interface swing. A aplicação consiste em um chat multi usuário que torna possível que o cliente envie uma mensagem para todos os demais clientes, conectados ao servidor, como também permite o envio de forma reservada, ou seja, o cliente seleciona um usuário e envia a mensagem apenas para este selecionado.

O desenvolvimento da interface gráfica será realizado na IDE Netbeans, veja na figura abaixo o resultado final da interface:

Assista os vídeos em sequência:

Lista de reprodução no youtube

Correção de bugs encontrados pelos leitores:

– Segundo o comentário da leitora Isadora Cardoso, existe um pequeno bug no chat, descrito como:

Se o usuário tentar se desconectar depois de enviar uma mensagem, ele não sai corretamente, ele continua conectado mesmo clicando no botão sair. Esse é o problema. Caso ele apenas entre na lista e não envie nada, não ocorre nenhum problema. E não estoura nenhuma exceção nem nada, é como se o botão não funcionasse mais depois de um envio…

Sendo assim, para corrigí-lo vá até para a classe ClienteFrame da aplicação cliente, onde será necessário realizar uma pequena alteração no código fonte do método btnSairActionPerformed(), o qual foi implementado na vídeo aula n° 06. Use o código abaixo para alterá-lo. 

private void btnSairActionPerformed(java.awt.event.ActionEvent evt) {                                       
        ChatMessage message = new ChatMessage();
        message.setName(this.message.getName());
        message.setAction(Action.DISCONNECT);
        this.service.send(message);
        disconnected();
}

– A leitora Camila encontrou o seguinte problema no chat:

quando dois clientes, com os nomes por exemplo 'a' e 'b', se eu for criar um terceiro cliente, e colocar o nome 'b' (que foi o ultimo que eu criei), o programa diz que não pode ser criado com esse nome, entretanto, se eu criar outro cliente com o nome 'a', ele cria normalmente. Já verifiquei o método connect no servidor, e a saída nele está saindo certo… e não sei mais onde procurar o erro ;x

Para corrigir esse erro, altere o método connect() da classe ServidorService para o código abaixo.

private boolean connect(ChatMessage message, ObjectOutputStream output) {
    if (mapOnlines.size() == 0) {
        message.setText("YES");
        send(message, output);
        return true;
    }

    if (mapOnlines.containsKey(message.getName())) { 
        message.setText("NO");
        send(message, output);
        return false;
    } else {
        message.setText("YES");
        send(message, output);
        return true;
    }
}

– Em um dos comentários o usuário Henrique descreve um erro ao sair do chat fechando a janela pelo botão [X]. A mensagem de que o cliente deixou o chat não chega aos demais clientes, ao invés disto, a última mensagem enviada pelo cliente que fechou a janela é reenviada em vez da mensagem de que saiu do bate-papo. Por algum motivo o objeto message da classe ServidorService não é atualizado no stream que foi enviado aos clientes. Para forçar esta atualização, foi necessário adicionar uma nova instancia para ChatMessage no processo, o qual então, substitui a antiga. Esta alteração é simples e foi realizada no método run() do listener da classe ServidorService, como mostra o código abaixo:

@Override
public void run() {
	ChatMessage message = null;
	try {
		//código omitigo, a alteração está no catch() abaixo
	} catch (IOException ex) {
		ChatMessage cm = new ChatMessage();
		cm.setName(message.getName());
		disconnect(cm, output);
		sendOnlines();
		System.out.println(message.getName() + " deixou o chat!");
	} catch (ClassNotFoundException ex) {
		Logger.getLogger(
			ServidorService.class.getName()).log(Level.SEVERE, null, ex);
	}
}

Download código fonte:

Download código fonte

 

 

 

Outras referencias:

Ballem

Marcio Ballem é bacharel em Sistemas de Informação pelo Centro Universitário Franciscano em Santa Maria/RS. Tem experiência com desenvolvimento Delphi e Java em projetos para gestão pública e acadêmica. Possui certificação em Java, OCJP 6.

Você pode gostar...