Ajuda - Sockets com Observer

8 respostas
rrigoni

Buenas,
Estou desenvolvendo uma engine de jogos em java atraves de sockets.

Estou com dificuldades na criação de um Observer, que dispare um evento no momento que o socket que já está aberto receber algum dado.
Estou usando multi-thread, cada conexão de cliente é disparado uma nova Thread. Preciso deixar esta conexão ativa, e apenas retornar a Thread em estado ativo no momento em que o cliente enviar dados novamente.

A parte do servidor está desta forma

socket = new ServerSocket(port);
            while(listening){                
            	Socket userSocket = this.socket.accept();
                GameEngineServerHandler engineServerHandler = new GameEngineServerHandler(userSocket);
                Thread threadEngineServerHandler = new Thread(engineServerHandler);
                threadEngineServerHandler.setName(socket.getInetAddress().getHostAddress()+":"+socket.getLocalPort());
                threadEngineServerHandler.start();
                engineServerThreadPool.addThread(threadEngineServerHandler);
            }

Em meu Handler no metodo run() necessito que a Thread durma enquanto não estiver recebendo dados.
E ativar novamente quando dados chegare para serem processados, pois o socket de cada cliente está com setKeepAlive(true);

Alguem pode me dar uma ajuda?

Ronaldo.

8 Respostas

T

Se puder evitar isso é melhor; use o conceito de pool de threads, porque você não vai conseguir atender a mais que 100 clientes simultaneamente com desempenho razoável se for usar uma thread para cada cliente.

rrigoni

Sim, já estou utilizando pool de threads.

Estou achando estranho permanecer com thread rodando enquanto o socket não receber dados, preciso implementar um observer que seja notificado no momento que o socket receber dados.

Ronaldo

T

Se precisasse de algo que fosse muito performático mesmo, usaria um socket assíncrono, tal como o descrito aqui:
http://java.sun.com/javase/6/docs/api/java/nio/channels/package-summary.html#multiplex

fantomas

Não sei se entendi direito…

Neste objeto engineServerThreadPool.addThread(threadEngineServerHandler); vc poderia implementar uma operação que ao receber um parametro que identificasse o client “acordaria” a thread, ou melhor ainda, um outro objeto associado a este pool que ficaria por conta apenas de fazer isto.
Localizar, ativar e pronto.

Que acha?

flws

rrigoni

thingol,

Preciso que seja sincrono mesmo, pois preciso saber o momento exato em que irei escrever para o cliente.

fantomas,
É exatamente isso que preciso implementar, mas socket não me oferece um método dizendo estar recebendo dados.

Ronaldo.

T

Eu já trabalhei com uma implementação desse tipo “listener” que é a tal da VB Winsock e digo: ela fica muito complicada de trabalhar. É que ela não sabe a divisão lógica entre suas mensagens, e você é obrigado a armazenar pedaços de buffers que o VB Winsock lhe forneceu gradualmente. E é por isso que a classe java.net.Socket não tem uma coisa desse tipo.

Em vez disso, deixe algumas threads lendo os bytes de cada socket aberto, e faça com que elas, ao acabarem de receber uma mensagem completa (lembre-se que isso pode levar vários “reads” - TCP Sockets têm esse problema de que as mensagens chegam “aos pedaços”), chamem o seu listener.

fantomas

Mas a coisa acho que funciona + ou - assim:

Toda vez que o Server recebe uma mensagem de algum client o processamento iniciado pela linha onde está o accept (this.socket.accept()) sai do “estado de espera” e segue em frente; ou seja, acredito que vc terá que fazer com que o client envie um identificador na mensagem para que vc possa recupera-lo dentro do objeto que irá localizar a thread correspondente.

flws

rrigoni

É isso mesmo que estou implementando, vou ter o custo de algumas threads lendo o buffer, mas isso será pouco comparado a complicação de se implementar um listener em sockets pois é questão do protocolo TCP mesmo.

Valeu galera.

Ronaldo.

Criado 16 de março de 2009
Ultima resposta 16 de mar. de 2009
Respostas 8
Participantes 3