同步,通知e等待 - 客户端Servidor

时间:2015-12-12 17:05:42

标签: java multithreading sockets client-server

我正在开发一个在客户端和服务器之间发送消息的应用程序,但是服务器类有一些如下所示的功能。有人可以在这些函数中帮助我,我把等待和通知函数和这些函数同步或不同步?我知道例如,当我进入我的HashMap utilizadores(共享资源)时,我必须使用notifys不知道是哪里。据说当没有新消息时,写消息的功能不应该等待了吗?

感谢您的帮助!

synchronized void getMessage(message){
while(!newMessages)
wait();
add(new Message());
notifyAll();
}
 public class SocketServidor extends Thread{
 private ServerSocket servidorSocket;
 private Socket socket;
 private static final int PORTA = 8080;

//hashmap: serve para enquanto cliente ir buscar as mensagens que lhe pertencem ao servidor; String nome cliente e respectiva mensagem
private Map<String, ObjectOutputStream> utilizadores = new HashMap<String, ObjectOutputStream>();  


public SocketServidor(){
try {
    servidorSocket = new ServerSocket(PORTA);               

    System.out.println("Lançou ServerSocket: " + PORTA);
    System.out.println("A aguardar conexão do cliente...");

    while(true){                                            

        socket = servidorSocket.accept();                   

        new Thread(new ListennerSocket(socket)).start();    
    }
} catch (IOException e) {
    e.printStackTrace();
}   
}


private class ListennerSocket implements Runnable {
private ObjectOutputStream output;                          
private ObjectInputStream input;                        

public ListennerSocket(Socket socket) {
    try {
        output = new ObjectOutputStream(socket.getOutputStream());
        input = new ObjectInputStream(socket.getInputStream());
    } catch (IOException e) {
        e.printStackTrace();
    }
}


@Override
public void run() {
    System.out.println("Nova conexão com o cliente " + socket.getInetAddress().getHostAddress());

    Mensagem mensagem = null;

    try {
        while((mensagem = (Mensagem) input.readObject() )!= null){                              Accao accao = mensagem.getAccao();                                  
            if(accao.equals(Accao.ONLINE)){
                boolean estaConectado = conectar(mensagem, output);
                if(estaConectado){
                    utilizadores.put(mensagem.getNomeClienteEnviaMensagem(),output);
                    adicionarListaContactosOnline();
                }
            }else if(accao.equals(Accao.OFFLINE)){
                sair(mensagem, output);
                System.out.println(mensagem.getNomeClienteEnviaMensagem() + " deixou a aplicacao QuequeAPP");
                return;                         
            }else if(accao.equals(Accao.ENVIAR_UM)){
                enviar_para_um(mensagem);
            }else if(accao.equals(Accao.ENVIAR_TODOS)){
                enviar_para_todos(mensagem);
            }
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        sair(mensagem, output);
        adicionarListaContactosOnline();
        e.printStackTrace();
    }
}


private boolean conectar(Mensagem mensagem, ObjectOutputStream output){         
    if(utilizadores.size() == 0){   
        mensagem.setMensagem("Conectado!");
        enviar(mensagem, output);
        return true;
    }

    for(Map.Entry<String, ObjectOutputStream> i : utilizadores.entrySet()){
        if(i.getKey().equals(mensagem.getNomeClienteEnviaMensagem())){
            mensagem.setMensagem("Não conectado!");
            enviar(mensagem, output);                                           
            return false;
        }else{
            mensagem.setMensagem("Conectado!");
            enviar(mensagem, output);
            return true;                                                        
        }
    }
    return false;                                                               
}


private void enviar(Mensagem mensagem, ObjectOutputStream output){              
    try {
        output.writeObject(mensagem);
    } catch (IOException e) {
        e.printStackTrace();
    }
}


private void sair(Mensagem mensagem, ObjectOutputStream output){                

    utilizadores.remove(mensagem.getNomeClienteEnviaMensagem());

    mensagem.setMensagem("Offline");

    mensagem.setAccao(Accao.ENVIAR_UM);

    enviar_para_todos(mensagem);
}




private void enviar_para_um(Mensagem mensagem){
    for(Map.Entry<String, ObjectOutputStream> mapa : utilizadores.entrySet()){
        if(mapa.getKey().equals(mensagem.getNomeClienteReceptorMensagem())) {       
            try {
                mapa.getValue().writeObject(mensagem);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


private void enviar_para_todos(Mensagem mensagem) {
    for(Map.Entry<String, ObjectOutputStream> mapa : utilizadores.entrySet()){
        if(!mapa.getKey().equals(mensagem.getNomeClienteEnviaMensagem())){
            mensagem.setAccao(Accao.ENVIAR_UM);
            try {
                mapa.getValue().writeObject(mensagem);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


private void adicionarListaContactosOnline(){
    Set<String> listaContactosOnline = new HashSet<String>();

    for(Map.Entry<String, ObjectOutputStream> mapa : utilizadores.entrySet()){
        listaContactosOnline.add(mapa.getKey());
    }

    Mensagem mensagem = new Mensagem();
    mensagem.setAccao(Accao.CONTACTOS_ONLINE);
    mensagem.setContactosOnline(listaContactosOnline);                  

    for(Map.Entry<String, ObjectOutputStream> mapa : utilizadores.entrySet()){
        mensagem.setNomeClienteEnviaMensagem(mapa.getKey());
        try {
            System.out.println("Contacto Online: " + mapa.getKey());                
            mapa.getValue().writeObject(mensagem);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

}

0 个答案:

没有答案