Chat em java - ObjectInputStream.readObject()

Bom galera, minha dúvida está exatamente no código do tópico. Estou desenvolvendo um siteminha operacional pra onde trabalho, mas estou começando a trabalhar com Sockets e iniciei a desenvolver um sis. de chat:

No Servidor, para receber novas mensagens ele tem o código:

public void run() { while (b_status_servidor) { try { Obj = (transObj) maq_ler.readObject(); escreverNoPrompt(Obj.getNOME() + " :: " + Obj.getMSG()); EspalharMSG(Obj); // maq_ler.; // recarregaMaq_leitora(CON); } catch (Exception ex) { Logger.getLogger(engine_chat_servidor.class.getName()).log(Level.SEVERE, null, ex); ex.printStackTrace(); } } }

No cliente, temos:

public void enviarMSG() { try { Obj.setMSG(campo_entrada.getText()); maq_escrever.writeObject(Obj); campo_entrada.setText(""); } catch (Exception ex) { Logger.getLogger(engine_chat_client.class.getName()).log(Level.SEVERE, null, ex); escrever_no_prompt("Sistema :: Falha ao enviar mensagem!"); campo_entrada.setText(""); ex.printStackTrace(); } }

O Sistema:

  • Connecta com sucesso.
  • Recebe a primeira mensagem com sucesso!
    x O cliente envia uma segunda mensagem, mas o servidor fica lendo repetitivamente o primeiro objeto enviado, e redistribui este também.

transObj é o objeto que contém como instâncias as informações básicas de quem enviou o comando, como getNOME() e getMSG().

Imagino que o primeiro objeto está “preso” e não sei como liberá-lo, sou iniciante em java.

Código inteiro do servidor:

package principal;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTextArea;

public class engine_chat_servidor {

    private ServerSocket Ss_AceitarCONs;
    public ArrayList<Socket> ArLi_LivroDeCONs = new ArrayList<Socket>();
    private int PORT;
    private Thread th_VigiaEntrada;
    public ArrayList<Thread> ArLi_LivroDeEntradas = new ArrayList<Thread>();
    private ArrayList<ObjectOutputStream> ArLi_LivroDeSAIDAs = new ArrayList<ObjectOutputStream>();
    private boolean b_status_servidor = true;
    private JTextArea campo_saida;

    public String toString() {
        return "Chat servidor - V1.0";
    }

    private void escreverNoPrompt(String msg_mm) {
        campo_saida.append(msg_mm + "\n");
    }

    public engine_chat_servidor(int PORT_mm, JTextArea campo_saida) {
        PORT = PORT_mm;
        this.campo_saida = campo_saida;
        criaServidor(PORT_mm);
    }

    public engine_chat_servidor(JTextArea campo_saida) {
        this.campo_saida = campo_saida;
    }

    public void criaServidor(int PORT_mm) {
        try {
            Ss_AceitarCONs = new ServerSocket(PORT_mm);
            th_VigiaEntrada = new Thread(new AceitarCONs());
            th_VigiaEntrada.start();
            escreverNoPrompt("Sistema :: Servidor criado!");
        } catch (IOException ex) {
            Logger.getLogger(engine_chat_servidor.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
        }

    }

    private class AceitarCONs implements Runnable {

        public void run() {
            escreverNoPrompt("Sistema :: Aguardando conexão.");
            while (b_status_servidor) {
                try {
                    ArLi_LivroDeCONs.add(Ss_AceitarCONs.accept());
                    ArLi_LivroDeEntradas.add(new Thread(new EntradaDeMSGs(ArLi_LivroDeCONs.get((ArLi_LivroDeCONs.size() - 1)))));
                    ArLi_LivroDeEntradas.get((ArLi_LivroDeEntradas.size() - 1)).start();
                    escreverNoPrompt("Sistema :: Usuário " + ArLi_LivroDeCONs.get((ArLi_LivroDeCONs.size() - 1)).getLocalAddress() + " Conectou no slot: " + (ArLi_LivroDeCONs.size() - 1));
                } catch (IOException ex) {
                    Logger.getLogger(engine_chat_servidor.class.getName()).log(Level.SEVERE, null, ex);
                    escreverNoPrompt("Sistema :: Tentativa de conexão mal sucedida!");
                    ex.printStackTrace();
                }
            }
        }
    }

    private class EntradaDeMSGs implements Runnable {

        private Socket CON;
        private ObjectInputStream maq_ler;
        private transObj Obj;

        public EntradaDeMSGs(Socket CON_mm) {
            CON = CON_mm;
            criarMaquinas(CON);
        }

        public void run() {
            while (b_status_servidor) {
                try {
                    Obj = (transObj) maq_ler.readObject();
                    escreverNoPrompt(Obj.getNOME() + " :: " + Obj.getMSG());
                    EspalharMSG(Obj);
//                    maq_ler.;
                    // recarregaMaq_leitora(CON);
                } catch (Exception ex) {
                    Logger.getLogger(engine_chat_servidor.class.getName()).log(Level.SEVERE, null, ex);
                    ex.printStackTrace();
                }
            }
        }

        private void recarregaMaq_leitora(Socket CON_mm) {
            try {
                maq_ler = new ObjectInputStream(CON_mm.getInputStream());
            } catch (IOException ex) {
                Logger.getLogger(engine_chat_servidor.class.getName()).log(Level.SEVERE, null, ex);
                ex.printStackTrace();
            }
        }

        private void criarMaquinas(Socket CON_mm) {
            try {
                maq_ler = new ObjectInputStream(CON_mm.getInputStream());
                ArLi_LivroDeSAIDAs.add(new ObjectOutputStream(CON_mm.getOutputStream()));
            } catch (Exception ex) {
                Logger.getLogger(engine_chat_servidor.class.getName()).log(Level.SEVERE, null, ex);
                ex.printStackTrace();
            }
        }
    }

    private void EspalharMSG(transObj Obj) {
        for (int i = 0; i < (ArLi_LivroDeSAIDAs.size()); i++) {
            try {
                ArLi_LivroDeSAIDAs.get(i).writeObject(Obj);
            } catch (IOException ex) {
                Logger.getLogger(engine_chat_servidor.class.getName()).log(Level.SEVERE, null, ex);
                RemoveCON(i);
                escreverNoPrompt("Sistema :: Slot: " + i + " foi removido.");
                ex.printStackTrace();
            }
        }
    }

    private void RemoveCON(int index) {
        ArLi_LivroDeCONs.remove(index);
        ArLi_LivroDeEntradas.remove(index);
        ArLi_LivroDeSAIDAs.remove(index);
    }
}

Descobri! D: …

O erro estava no ObjectOutputStream ‘-’

public void enviarMSG() { try { Obj.setMSG(campo_entrada.getText()); maq_escrever.writeObject(Obj); campo_entrada.setText(""); maq_escrever.reset(); } catch (Exception ex) { Logger.getLogger(engine_chat_client.class.getName()).log(Level.SEVERE, null, ex); escrever_no_prompt("Sistema :: Falha ao enviar mensagem!"); campo_entrada.setText(""); ex.printStackTrace(); } }

adicionei o código:

maq_escrever.reset();

ao cliente, e funcionou, limpou o fluxo dos objetos já enviados e enviou um novo. :smiley: ‘-’ :q …

ArLi_LivroDeCONs.add(Ss_AceitarCONs.accept()); ArLi_LivroDeEntradas.add(new Thread(new EntradaDeMSGs(ArLi_LivroDeCONs.get((ArLi_LivroDeCONs.size() - 1))))); ArLi_LivroDeEntradas.get((ArLi_LivroDeEntradas.size() - 1)).start(); escreverNoPrompt("Sistema :: Usuário " + ArLi_LivroDeCONs.get((ArLi_LivroDeCONs.size() - 1)).getLocalAddress() + " Conectou no slot: " + (ArLi_LivroDeCONs.size() - 1));

será q não ficaria um pouco melhor se fosse assim?

Socket sk = Ss_AceitarCONs.accept(); //se o retorno for nulo? ArLi_LivroDeCONs.add(sk); Thread th = new Thread(new EntradaDeMSGs(sk)); ArLi_LivroDeEntradas.add(th); th.start(); escreverNoPrompt("Sistema :: Usuário " + sk.getLocalAddress() + " Conectou no slot: " + (ArLi_LivroDeCONs.size() - 1));

Fica mais legível neh.
Seria apenas essa a melhoria ou vc diz que ficaria melhor por questões de hardware também? ‘-’ …

não intendi:

aquela Thread ficará travana naquele comando até receber um retorno não nulo ._. … até ocorrer conexão . ‘-’ …

Por favor, não use tags informativas como [Resolvido] para dizer o óbvio, como [Dúvida], [Ajuda], [Socorro] ou [Urgente].