Socket e espera de dados

Galera, minha dúvida é o seguinte: Eu estou desenvolvendo um chat (mas já tive a mesma dúvida em outras situações), o Client precisa receber infomações aleatórias como por exemplo um usuário que entrou no sistema, o Client precisa receber a notificação que aquele usuário entrou para ele saber que este está disponível para o chat. Ai minha dúvida é a seguinte, eu devo utilizar uma thread que fica responsável por receber mensagens do servidor? (Assim como a do servidor que sempre espera uma mensagem de um client). Ou é melhor fazer um esquema de a cada X segundos o client solicita atualizações do servidor?
Na primeira abordagem eu fico com o seguinte problema: Ao abrir o thread, tudo terá que passar por ele, pois se eu “esperar” mensagens em outro local, irá dar conflito, pois terá 2 sockets esperando mensagens do mesmo endereço e porta.
Na segunda abordagem eu fico com o seguinte problema: As informações não serão sincronizadas da forma correta (ao meu ver), pois o client que precisará fazer a solicitação de forma periódica.

Além destes problemas, gostaria de tirar uma dúvida sobre Multicast. O chat que estou implementando utilizará o multicast e segundo os testes que fiz o endereço “224.0.0.0” já difere do “224.0.0.1”, ou seja cada acréscimo já me da um grupo multicast diferente, correto? Como eu posso manter uma estrutura para saber quais endereços eu possuo disponíveis? Pensei numa HashMap, porém quando um endereço for liberado, como obtê-lo de novo para “dar” a outro client, tendo em vista que pretendia fazer ele crescente. O primeiro Client recebe 224.0.0.0, o segundo 224.0.0.1 e etc.

Muito obrigado a todos que poderem dar qualquer tipo de ajuda!

Alguém? Estou procurando sobre isto desde ontem e não encontro nenhuma implementação que o client necessite receber atualizações do tipo “tal usuário acabou de entrar”, logo nenhuma necessita que o client possua uma thread para receber mensagens a todo instante. Alguém pode dar uma luz sobre isso? Como deixar o client receber atualizações sem impedir dele receber mensagens em um método específico? Quero que ele possa receber mensagens aleatórias, mas em um método especifico ele possa receber uma mensagem que não caia no thread que está esperando mensagens aleatórias! Digamos que faz parte do funcionamento do método que ele receba essa mensagem lá! Quem poder ajudar, agradeço muito!

[quote=thiagosampaio]Galera, minha dúvida é o seguinte: Eu estou desenvolvendo um chat (mas já tive a mesma dúvida em outras situações), o Client precisa receber infomações aleatórias como por exemplo um usuário que entrou no sistema, o Client precisa receber a notificação que aquele usuário entrou para ele saber que este está disponível para o chat. Ai minha dúvida é a seguinte, eu devo utilizar uma thread que fica responsável por receber mensagens do servidor? (Assim como a do servidor que sempre espera uma mensagem de um client). Ou é melhor fazer um esquema de a cada X segundos o client solicita atualizações do servidor?
Na primeira abordagem eu fico com o seguinte problema: Ao abrir o thread, tudo terá que passar por ele, pois se eu “esperar” mensagens em outro local, irá dar conflito, pois terá 2 sockets esperando mensagens do mesmo endereço e porta.
Na segunda abordagem eu fico com o seguinte problema: As informações não serão sincronizadas da forma correta (ao meu ver), pois o client que precisará fazer a solicitação de forma periódica.

Além destes problemas, gostaria de tirar uma dúvida sobre Multicast. O chat que estou implementando utilizará o multicast e segundo os testes que fiz o endereço “224.0.0.0” já difere do “224.0.0.1”, ou seja cada acréscimo já me da um grupo multicast diferente, correto? Como eu posso manter uma estrutura para saber quais endereços eu possuo disponíveis? Pensei numa HashMap, porém quando um endereço for liberado, como obtê-lo de novo para “dar” a outro client, tendo em vista que pretendia fazer ele crescente. O primeiro Client recebe 224.0.0.0, o segundo 224.0.0.1 e etc.

Muito obrigado a todos que poderem dar qualquer tipo de ajuda![/quote]

Estes dias respondi algo sobre chat:

Rapaz, dá pra fazer isso que vc quer, mas imagina se o servidor tiver que “saber” o IP de todos os usuários conectados a ele? Mesmo que ponha cada cliente diretamente conectado, imagina uma sala com 50 usuários… vai arrebentar seu servidor se existirem muitas salas.
Melhor fazer isso que vc tá dizendo com os x segundos de verificação já que é apenas um chat.
Vc terá que inventar uma forma de trabalhar com estas informações aleatórias.

Se tiver interesse em um fonte ou uma consultoria, me manda uma MP.

Minha ideia é a seguinte. Um usuário se conecta ao servidor para se autenticar. Este mesmo servidor fica responsável por enviar atualizações para o usuário. Estas atualizações são: tal usuário fez login, tal usuário fez logout, etc. As mensagens em si serão transmitidas de usuário para usuário através de um grupo multicast. Porém para os dois usuários saberem qual o grupo multicast, o servidor terá q definir isso no momento que um deles inicia uma conversa com o outro. Por isso achei necessário o servidor manter uma estrutura com todos os endereços multicast disponíveis. Em relação à forma que os usuários receberão estas atualizações que é minha dúvida, eu usualmente utilizo um thread no client que recebe mensagens do servidor a todo momento, e esta thread chama métodos dependendo da mensagem recebida, ou seja, a thread “espalha” a mensagem no programa, dependendo de qual seja a mensagem. Esta forma de fazer o client solicitar atualizações periodicamente me surgiu na mente, pois eu possuo um método que solicita do servidor um endereço multicast para uma nova conversa, este endereço deve ser retornado pelo método, logo eu não posso “esperar” que este endereço chegue no thread citado, pois o thread não terá o poder de continuar um método de onde ele parou! Preciso do endereço no método que solicito este endereço ao servidor. Com a abordagem da solicitação de atualização periódica, eu acabo com este problema, fazendo com que o thread utilize o socket a cada x segundos apenas, liberando-o o restante do tempo. Utilizando a tag synchronized, o problema é resolvido! Porém eu particularmente não gostei desta abordagem, achei meio “gambiarra”. Você (ou mais alguém) tem alguma sugestão quanto a isso?

É, mas acho que não existe outra forma.
Como lhe disse, para fazer o que quer, supondo dois computadores comunicando entre si instantaneamente, cada um vai precisar ocupar 2 portas. Uma pra entrada e outra pra saída dos dados.
agora pense 3 computadores. conectados serão 3 portas pra cada e assim sucessivamente. Imagina agora 50 carinhas querendo comunicar entre si instantaneamente… Isso ficaria bacana para um jogo, mas lembre-se de que o servidor, normalmente não deve conhecer (ter gravado) o IP do usuário para lhe enviar resposta. E outra… O que aconteceria se a porta do usuário estiver ocupada? Terá que preparar o computador pra fazer uma varredura de portas. Vc pode fazer isso se não tiver preocupado com segurança.

Mas se todo mundo dependerá do servidor central, é mais fácil atraves dele concentrar todas as requisições e respostas dos outros usuários, e somente o usuario requisitar as atualizações deste servidor quando vencer o tempo do delay. O delay não precisa ser de 7 segundos. pode ser de milésimos de segundos.
como lhe sugerí, pode usar uma flag de um bit 0 informando se não existe informação nova e 1 se existe.
isso pode ser feito umas 1000 vezes tranquilamente sem problemas para o usuário e o servidor. Melhor o que ficar abrindo uma pancada de portas e expondo os IPs dos usuários desnecessariamente.