Good 4 Denunciar post Postado Janeiro 24, 2013 Estou desenvolvendo um sistema de chat em js+java, conexão via web socket. Quando um usuário se conecta, é gravado a id do usuário num array. Acesse o código aqui, pois aqui no imasters ficou tudo bugado: http://pastebin.com/Rbvmw6VV Como puderam ver, a função armazena guarda a id do novo usuário. Então, quando armazenado o servidor vai enviar para o cliente alguns dados pela função send do websocket. A função enviarParaTodos está funcionando normalmente, mas preciso fazer uma função que envie para todos os usuários exceto eu. Não sei como fazer :S E comecei Java a pouco tempo :D Compartilhar este post Link para o post Compartilhar em outros sites
Vergil 15 Denunciar post Postado Janeiro 24, 2013 Primeiro, você não precisa fazer isso: public boolean armazena(String newId) { for (int i = 0; i < LISTA_DE_NOMES.size(); i++) { if (LISTA_DE_NOMES.get(i).equals(newId)) return false; } LISTA_DE_NOMES.add(newId); return true; } Utilize uma implementação da interface java.util.Set . Implementações de Set não aceitam repetições. Quanto a repetição, bastaria que você tivesse gravado o seu usuário numa variável. E no momento de enviar as mensagens não enviar mensagem para usuário com id igual ao seu. Compartilhar este post Link para o post Compartilhar em outros sites
Good 4 Denunciar post Postado Janeiro 25, 2013 Vergil, como você pode ver.. Naquela função que envia para todos, aquele for tem um tal de Websocket c. Ele não dá para fazer um condicional. E para enviar usando aquela lista de usuários conectados, eu teria que chamar a conexão deste tal usuário.. O qual não da certo.. :S Af isso não tem como editar o post depois de um tempo e nem pode juntar os 2 posts quando o post for meu, então ninguém reclama de flood nem nada.. ------------------------------ As conexões ficam salvadas numa lib do Websocket. A lista de ids de usuários conectados ficam na LISTA_DE_NOMES. Como você pode ver, tem um LISTA_DE_NOMES.add(newId); Como eu posso inserir a variável de conexão junto com este novo valor do array? Ficando mais ou menos assim: LISTA_DE_NOMES { 0: (1,var conexao), 1: (451,var conexao)} A função: public boolean armazena(int newName, WebSocket conn) { for (int i = 0; i < LISTA_DE_NOMES.size(); i++) { if (LISTA_DE_NOMES.get(i).equals(newName)) return false; } LISTA_DE_NOMES.add(newName); return true; } Compartilhar este post Link para o post Compartilhar em outros sites
Vergil 15 Denunciar post Postado Janeiro 25, 2013 Poderia me dar um exemplo? :S Vou te dar uma ideia. Partamos do ponto em que os ids de usuários são únicos. Dessa forma você resolveria seu problema com um mapa (http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Map.html). Dessa forma você teria uma mapa onde as chaves seriam os ids dos usuários e os valores seriam por exemplo o objeto de conexão. public class MinhaClasse { private Map<Integer, WebSocket> conexoes; private static Integer meuId = 4521548; public MinhaClasse() { this.conexoes = new HashMap<Integer, WebSocket>(); } public void armazena(int id, WebSocket conn) { this.conexoes.put(id, conn); } public void enviaParaTodos(String texto) { for (WebSocket ws : this.conexoes.values()) { ws.send(texto); } } public void enviaParaTodosExecetoAMim(String texto) { for (Integer chave : this.conexoes.keySet()) { if (chave != meuId) { this.conexoes.get(chave).send(texto); } } } } No exemplo acima, eu não compilei, talvez tenha algum erro de sintaxe. E também não adicionei nem um import. Fica a ideia. Compartilhar este post Link para o post Compartilhar em outros sites
Good 4 Denunciar post Postado Janeiro 25, 2013 Vergil, o último problema.. Na função armazena: public boolean armazena(int uid, WebSocket conn) { boolean jaConectado = false; for (Integer chave : this.LISTA_DE_NOMES.keySet()) { if (chave == uid) { jaConectado = true; break; } } if(!jaConectado){ this.LISTA_DE_NOMES.put(uid,conn); } return true; } quando clico em Run, e que o usuário se conecta fica dando problema na linha do for (linha 154, a linha 57 chama a função armazena): java.lang.NullPointerException at Servidor.armazena(Servidor.java:154) at Servidor.onMessage(Servidor.java:57) at org.java_websocket.server.WebSocketServer.onWebsocketMessage(WebSocketServer.java:457) at org.java_websocket.WebSocketImpl.decodeFrames(WebSocketImpl.java:365) at org.java_websocket.WebSocketImpl.decode(WebSocketImpl.java:154) at org.java_websocket.server.WebSocketServer$WebSocketWorker.run(WebSocketServer.java:625) Compartilhar este post Link para o post Compartilhar em outros sites
Vergil 15 Denunciar post Postado Janeiro 30, 2013 Realmente eu não entendi o porquê de você ter complicado tanto o código com isso: public boolean armazena(int uid, WebSocket conn) { boolean jaConectado = false; for (Integer chave : this.LISTA_DE_NOMES.keySet()) { if (chave == uid) { jaConectado = true; break; } } if(!jaConectado){ this.LISTA_DE_NOMES.put(uid,conn); } return true; } Tente entender primeiro como funciona o Map. É importante ler a documentação http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Map.html E outra, por padrão, nós só nomeamos objetos em caixa alta quando estes são constantes (final). Agora, pra você ter ajuda quanto ao erro, é de suma importância que você aponte a linha exata que está dando erro. Você disse que está dando erro na linha 154 e agora eu te pergunto: o que tem na linha 154??? Ao que tudo indica, você pode não ter instanciado o mapa de conexões. Confira isso. Compartilhar este post Link para o post Compartilhar em outros sites
Good 4 Denunciar post Postado Janeiro 30, 2013 AAhh, desculpe.. a linha 154 é: for (Integer chave : this.LISTA_DE_NOMES.keySet()) { Entendi, estou vendo que este for para validar se o usuário já está online é desnecessário. Visto que o Map já grava, não aceitando valores repetidos. Mas como eu posso fazer com que retorne um true ou false, para enviar ao cliente se ele pode se conectar ou não? Obrigado! Compartilhar este post Link para o post Compartilhar em outros sites
Vergil 15 Denunciar post Postado Janeiro 31, 2013 Como eu disse, você esqueceu de instanciar o mapa de conexões. No código que te passei antes eu instancio o mapa dentro do construtor da classe. Mas como eu posso fazer com que retorne um true ou false, para enviar ao cliente se ele pode se conectar ou não? Do mesmo jeito que você envia mensagem de texto pro usuário. Compartilhar este post Link para o post Compartilhar em outros sites
Good 4 Denunciar post Postado Janeiro 31, 2013 Olha como o código está atualmente: http://pastebin.com/dUEsXmTX Olhando o código atual, você pode ver que está quase completamnete igual o seu. Eu adicionei um ) throws UnknownHostException { na parte do construtor da classe. Se eu tirar, dá um erro dizendo que precisa colocar.. :S A parte de validar se o usuário está na lista de conexoes eu já sei como fazer... vlw Compartilhar este post Link para o post Compartilhar em outros sites
Morpheus#2005 1 Denunciar post Postado Fevereiro 1, 2013 Pergunta...o motivo do PARA TODOS, também inclui você rsss obvio. Mensagem para TODOS ON, TODOS OFF(inbox), TODOS ADMINISTRADORES, TODOS USUARIOS ? Vc já pensou nisso ? Porque não criar classes ( Administrador,Usuarios,etc...), sendo assim daria para controlar e vc nao precisaria SETAR no codigo exclusivamente para vc. Good Luckk Compartilhar este post Link para o post Compartilhar em outros sites
Good 4 Denunciar post Postado Fevereiro 1, 2013 Não Morpheus... Este sistema de enviar mensagens é apenas para os usuários que estiverem online ao servidor. Um exemplo: eu me conecto ao servidor. O servidor vai retornar alguns dados, mas esses dados não podem ser enviados para mim. Por isso preciso criar a função que envia para todos, exceto eu. E a função que envia todos, em geral! Há diversas informações que não devem ser enviadas para mim. Pois se não daria problema, visualmente. Compartilhar este post Link para o post Compartilhar em outros sites
Bezerk 3 Denunciar post Postado Fevereiro 2, 2013 Estude o padrão de projetos Observer, ele é fácil de implementar e acho que ajuda a resolver o seu problema. Compartilhar este post Link para o post Compartilhar em outros sites
Good 4 Denunciar post Postado Fevereiro 4, 2013 Oww, mas eu tenho noção básica. Não sei fazer quase nada, basicamente só criar funções simples, colocar string, int, boolean, etc.. ajudae nesse problema.. :S Compartilhar este post Link para o post Compartilhar em outros sites
Vergil 15 Denunciar post Postado Fevereiro 4, 2013 ajudae nesse problema.. E que problema você está tendo agora? Compartilhar este post Link para o post Compartilhar em outros sites
Good 4 Denunciar post Postado Fevereiro 4, 2013 O mesmo.. Na postagem #9: http://forum.imasters.com.br/topic/485528-enviar-para-todos-usurios-conectados/#entry1931419 vlw Compartilhar este post Link para o post Compartilhar em outros sites
Vergil 15 Denunciar post Postado Fevereiro 4, 2013 Não conheço a classe WebSocketServer, mas ao que tudo indica o construtor padrão dela tem um throws para a exceção UnknownHostException. O que você tem a fazer é circundar o código do seu construtor com um try/catch ou fazer o que você já fez, passar a exceção pra frente com um throws. Compartilhar este post Link para o post Compartilhar em outros sites