Ola pessoal, não sei se aqui é o melhor lugar para postar minha dúvida, mais acho que ela é um pouco básica.
Vamos la, então pessoal, estou construindo um bate-papo com Swing só pra aprender um pouco mais sobre threads mesmo, nada de comercial, logo não liguem para algumas coisinhas feias que estou fazendo como não implementar runnable e outras coisas. Li um pouco sobre serialização e ja estudei um pouco sobre threads no livro pra certificação, mas ainda estou com algumas duvidas no meu projeto como:
- estou tentando fazer a comunicação com o servidor passando um objeto no fluxo (ObjectOutputStream) acho que ate ai tudo bem.
- Estou tentando gerar uma nova thread para cada socket recebido pelo servidor
- para cada conexao no servidor eu mantenho uma lista dos conectados
- Para cada thread criada gostaria de uma mensagem enviada por um usuario seja enviada para todos que estao conectados.
OBS: algumas funcionalidades não estao implementadas, gostaria mesmo é que me ajudem a identificar o erro.
Desde já agradeço pessoal
Vou postar todo o codigo, vai ficar um pouco grande.
[code]public class Usuario implements Serializable {
private InetAddress adress;
private String nickName;
private boolean online;
private String ultimaMensagem;
public Usuario() {
}
public Usuario(String nickName, InetAddress adress) {
this.nickName = nickName;
this.online = true;
this.adress = adress;
}
public String getUltimaMensagem() {
return ultimaMensagem;
}
public void setUltimaMensagem(String msg) {
this.ultimaMensagem = msg;
}
public String getNickName() {
return nickName;
}
public void setNickName(String name) {
this.nickName = name;
}
public boolean isOnline() {
return online;
}
public void setOnline(boolean online) {
this.online = online;
}
public InetAddress getAdress() {
return adress;
}
public void setAdress(InetAddress adress) {
this.adress = adress;
}
private void readObject(ObjectInputStream in) {
try {
in.defaultReadObject();
this.nickName = in.readUTF();
this.online = in.readBoolean();
this.ultimaMensagem = in.readUTF();
this.adress = (InetAddress)in.readObject();
} catch (Exception e) {
throw new ValidationException("Falha in Usuario.readObject", e);
}
}
private void writeObject(ObjectOutputStream out) {
try {
out.defaultWriteObject();
out.writeUTF(this.nickName);
out.writeBoolean(this.online);
out.writeUTF(this.ultimaMensagem);
out.writeObject(this.adress);
} catch (Exception e) {
throw new ValidationException("Falha in Usuario.writeObject", e);
}
}
@Override
public String toString() {
return "Usuario{" + "name=" + nickName + ", ipAdress=???" + ", online=" + online + ", ultimaMensagem=" + ultimaMensagem + '}';
}
}
[/code]
[code]public class EntrarUI extends javax.swing.JFrame {
private DataInputStream in;
private DataOutputStream out;
private Socket clientSocket;
private Usuario user;
/**
* Creates new form EntrarUI
*/
public EntrarUI() {
initComponents();
//centralizar
this.setLocationRelativeTo(null);
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
entrar();
}
private void entrar() {
if (txtNomeApelido.getText().isEmpty() || txtNomeApelido.getText() == null) {
throw new ValidationException("Informe seu Nome/Apelido para acessar o bate-papo.", null);
}
if (txtIpServidor.getText().isEmpty() || txtIpServidor.getText() == null) {
throw new ValidationException("Informe o ip do servidor para acessar a sala de bate-papo.", null);
}
if (txtPorta.getText().isEmpty() || txtPorta.getText() == null) {
throw new ValidationException("Informe a porta do servidor para acessar a sala de bate-papo.", null);
}
String nickName = txtNomeApelido.getText();
String servidor = txtIpServidor.getText();
int porta = Integer.parseInt(txtPorta.getText());
if (estabelecerConexao(servidor, porta)) {
this.user = new Usuario(nickName, clientSocket.getLocalAddress());
new MessengerClientUI(user, clientSocket).setVisible(true);
this.dispose();
}
}
private boolean estabelecerConexao(String server, int port) {
try {
this.clientSocket = new Socket(server, port);
return clientSocket != null ? true : false;
} catch (Exception e) {
throw new ValidationException("Falha ao tentar obter conexão com o servidor.", e);
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/*
* Set the Nimbus look and feel
*/
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/*
* If Nimbus (introduced in Java SE 6) is not available, stay with the
* default look and feel. For details see
* http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(EntrarUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(EntrarUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(EntrarUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(EntrarUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new EntrarUI().setVisible(true);
}
});
}
}
[/code]
public class MessengerClientUI extends javax.swing.JFrame {
private Usuario user;
private ObjectOutputStream out;
private ObjectInputStream in;
private Socket clientSocket;
public MessengerClientUI(Usuario user, Socket socket) {
this();
try {
System.out.println("criou out");
this.clientSocket = socket;
this.user = user;
this.out = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException ex) {
throw new ValidationException("Falha ao iniciar fluxo de saida.", ex);
}
}
public MessengerClientUI() {
initComponents();
//centralizar
this.setLocationRelativeTo(null);
}
private void btnLimparActionPerformed(java.awt.event.ActionEvent evt) {
limpar();
}
private void btnEnviarActionPerformed(java.awt.event.ActionEvent evt) {
enviarMensagem();
}
private void atualizarBateBapo() {
try {
ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
Usuario userNewMessage = (Usuario) in.readObject();
insertNewMessage(user);
} catch (Exception e) {
throw new ValidationException("Falha ao atualizar mensagens enviada pelos usuarios ", e);
}
}
private void insertNewMessage(Usuario user) {
//se não tiver nada escrito retorna uma String vazia, caso contrario o texto
String batePapoAntigo = txtaBatePapo.getText() != null ? txtaBatePapo.getText() : "";
String novaMensagem = user.getUltimaMensagem();
String mensagemAtualizada = batePapoAntigo
+ "\n\n<<" + user.getNickName() + ">>"
+ "\nMensagem: " + user.getUltimaMensagem();
txtaBatePapo.setText(mensagemAtualizada);
}
private void enviarMensagem() {
if (txtaMensagem.getText().isEmpty() || txtaMensagem.getText() == null) {
throw new ValidationException("Informe pelomenos um caractere");
}
user.setUltimaMensagem(txtaMensagem.getText().trim());
try {
out.writeObject(user);
out.flush();
} catch (IOException ex) {
throw new ValidationException("Falha ao enviar dados do cliente ao servidor.", ex);
}
}
private void limpar() {
}
public static void main(String args[]) {
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/*
* If Nimbus (introduced in Java SE 6) is not available, stay with the
* default look and feel. For details see
* http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(MessengerClientUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MessengerClientUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MessengerClientUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MessengerClientUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MessengerClientUI().setVisible(true);
}
});
}
}
public class Server {
private static List<Usuario> usuarios = new ArrayList<>();
public Server() {
}
public static void main(String[] args) {
ServerSocket server = null;
try {
server = new ServerSocket(ConfigServer.PORT);
System.out.println("server on\n\n\n");
} catch (Exception e) {
throw new ValidationException("Falha ao iniciar o servidor", e);
}
while (true) {
try {
Socket client = server.accept();
atualizaListaUsuarios(client);
ConnectionManagerServer manager = new ConnectionManagerServer(client, usuarios);
} catch (Exception e) {
throw new ValidationException("Falha ao obter cliente no servidor", e);
}
}
}
/**
* Atualiza a lista de clientes conectados ao bate-bapo
*
* @param Socket
*/
private static void atualizaListaUsuarios(Socket client) {
try {
ObjectInputStream inServer = new ObjectInputStream(client.getInputStream());
Usuario user = (Usuario) inServer.readObject();
System.out.println(user.toString());
usuarios.add(user);
} catch (Exception e) {
e.printStackTrace();
throw new ValidationException("Falha ao obter dados do cliente #"
+ client.getInetAddress().getHostAddress(), e);
}
}
}
Aqui está a danada
package util;
import client.model.Usuario;
import java.io.*;
import java.net.Socket;
import java.util.List;
public class ConnectionManagerServer extends Thread {
private List<Usuario> usuarios;
private Socket client;
private ObjectInputStream in;
private ObjectOutputStream out;
/**
* Este construtor serve como um Eco das mensagens, ou seja, ele recebe e
* repassa
*
* @param aSocket
*/
public ConnectionManagerServer(Socket aSocket, List<Usuario> usuarios) {
try {
this.client = aSocket;
this.usuarios = usuarios;
in = new ObjectInputStream(client.getInputStream());
out = new ObjectOutputStream(client.getOutputStream());
this.start();
} catch (IOException e) {
throw new ValidationException("IOException do client #"
+client.getInetAddress().getHostAddress());
}
}
public void run() {
try {
Usuario user = (Usuario)in.readObject();
} catch (Exception e) {
throw new ValidationException("Falha ao ECOAR objeto em run()", e);
}
}
private void sendToAll() {
for (Usuario user : usuarios) {
try {
ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
out.writeObject(user);
} catch (Exception e) {
throw new ValidationException("Falha ao iniciar fluxo de xaida para as mensagens do servidor.", e);
}
}
}
}
Se alguem precisa eu posso enviar projeto(netbeans)