| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/09/2002 13:32:30
|
Guilherme Silveira
Administrador
Membro desde: 14/08/2002 10:09:26
Mensagens: 1096
Localização: Sao Paulo
Offline
|
Depois de uma longe discussao numa lista, decidi copiar aqui tambem o que sei sobre chats, assim quem tiver duvidas do assunto vao saber onde perguntar, se nao solucionar o problema.
Um chat que se mantem no servidor implementado por servlets/jsp costuma possuir dois frames: o TEXTO (onde tem a barra de rolagem) e o FORMULARIO. O protocolo eh sempre HTTP claro.
O formulario pode usar o metodo POST/GET mas o metodo recomendado pode ser o PUT, uma vez que indica enviar algo para alterar uma pagina.
A diferenca cosmetica numa servlet sera qual metodo devera ser implementado, doGet, doPost ou doPut.
A servlet que recebe o formulario ira processar o request e devolver um novo formulario.
Pronto, a segunda parte esta pronta, falta a primeira parte/frame.
Ele eh feito atraves de uma outra/mesma servlet que NAO FECHA A CONEXAO COM O CLIENTE (exemplos: uol, terra). Algumas pessoas pensam que isso ira abusar de conexoes, porem eh a tecnica utilizada por todos os grandes chats. Fora dessa soh existe o metodo de reloads que nem irei comentar.
Desse jeito, essa servlet mantem uma lista com os streams de saida (OutputStream/Writer) e quem eh quem (esses chats sempre fazem aquele opcao de mandar mensagem privada para "Joca Maloca").
Essa servlet ira dormir ate o usuario clicar STOP no browser (ira jogar uma excecao no codigo: stream fora fechada) ou fechar a janela (idem)..... assim voce sabe que o usuario saiu da sala. Claro que voce pode criar um botao SAIR que tambem devera tirar o usuario da sala.
Por ultimo voce precisa fazer com que a cada nova mensagem na servlet que processa FORMULARIOS, essas sejam escritas nos usuarios que estao conectados na servlet de TEXTO (se nao for a mesma).
Para isso voce pode:
- para cada novo formulario, processar umvetor com uma lista de usuarios conectados e enviar a mensagem para cada Stream deles
- durante o sleep da servlet de TEXTO, checar se existe algo novo e jogar este novo no stream do usuario.
O primeiro metodo eh muito mais inteligente e rapido, apesar de efetuar uma conexao direta entre duas servlets (nao muito orientado a objeto), mas eh um problema que pode ser solucionado sem muita dor de cabeca.
Bom, eh isso, espero ter solucionado o problema daqueles que nao conseguem imaginar como fazer um chat sem tempos de reload....
Quaisquer duvidas, podem escrever
Guilherme Silveira
|
-------------------------------------------------------
Guilherme Silveirahttp://blog.caelum.com.br
 |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/09/2002 13:49:31
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
Tenho uma solucao mais legal ainda!
Cria um objeto estatico que vai ser usado como mutex na servlet
Ai, voce usa o esquema do Guilherme, imprime tudo o que voce ja tem num buffer (static StringBuffer como variavel de classe de servlet, por exemplo), e poe diretao:
Assim a servlet vai ficar esperando, e várias outras vao ficar esperando. Quando alguem manda uma mensagem, atraves de outra servlet, voce sincroniza atraves dessa variavel CHAT, e da um notifyAll:
Todo mundo vai sair do Wait! Ai la voce le o que o cara colocou no buffer, e volta pro wait!
legal neh?
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/09/2002 13:54:17
|
Guilherme Silveira
Administrador
Membro desde: 14/08/2002 10:09:26
Mensagens: 1096
Localização: Sao Paulo
Offline
|
essa eh a complicacao q eu falei q nao seria o problema de uma grande dor de cabeca....
mas com certeza ainda acho melhor criar um objeto chamado Cliente ou Usuario com um metodo addMessage() e passa um objeto Message() para ele.
Esse metodo deve entao simplesmente processar essa mensagem.
Eh mais orientado a objeto do que a tua solucioneba meia boca (to brincando)
Gui
|
-------------------------------------------------------
Guilherme Silveirahttp://blog.caelum.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/09/2002 14:01:18
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
Mas entao no seu caso, as servlets ficam o tempo TODO verificando se tem mensagem nova? Isso eh loucura total! PRECISA de sincronização.
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/09/2002 14:04:01
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
Digo isto porque voce deu duas solucoes:
Guilherme Silveira wrote:
- para cada novo formulario, processar umvetor com uma lista de usuarios conectados e enviar a mensagem para cada Stream deles
Ok, voce envia a mansagem pro stream do cliente. Mas como a thread q ta servindo esse cliente vai descobrir que o stream tem coisa nova? Voce fica dentro de um while(true)?
Guilherme Silveira wrote:
- durante o sleep da servlet de TEXTO, checar se existe algo novo e jogar este novo no stream do usuario.
Esta aqui é muito ruim! De quanto tempo eh o sleep? Se for pouco, vai sobrecarregar o servidor. Se for muito, vai ter lag na conversa!
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/09/2002 14:10:53
|
Guilherme Silveira
Administrador
Membro desde: 14/08/2002 10:09:26
Mensagens: 1096
Localização: Sao Paulo
Offline
|
esse segundo q vc falou era o meu primeiro q eu descartei la no texto
o primeiro q vc falou eh o meu segundo no texto q eu adicionei:
O primeiro metodo eh muito mais inteligente e rapido, apesar de efetuar uma conexao direta entre duas servlets (nao muito orientado a objeto), mas eh um problema que pode ser solucionado sem muita dor de cabeca.
que eh exatamente o q vc fez, efetuou a conexao direta enter as duas servlets atraves de um objeto/metodo estatico das duas.
o melhor ainda seria que esse fizesse esse metodo/objeto estatico um pouco mais orientado a objeto e nao soh um simples mutex inutilex
gui
|
-------------------------------------------------------
Guilherme Silveirahttp://blog.caelum.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/09/2002 14:15:20
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
Mas o seu vetor de OutputStreams (buffers) dos clientes eh estatico.
Nao tem como fugir.
Voce pode fazer um singleton, se qusier disfarcar.
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/09/2002 14:17:23
|
Guilherme Silveira
Administrador
Membro desde: 14/08/2002 10:09:26
Mensagens: 1096
Localização: Sao Paulo
Offline
|
o vetor eh estatico mas nao visivel atraves de um getVector()
e sim teria um estatico sendMessageToUser(User,Message);
Gui
|
-------------------------------------------------------
Guilherme Silveirahttp://blog.caelum.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/09/2002 22:47:08
|
Rafael Steil
Administrador
![[Avatar]](/images/avatar/8e296a067a37563370ded05f5a3bf3ec.jpg)
Membro desde: 31/08/2002 02:35:53
Mensagens: 5984
Localização: São Paulo
Offline
|
Eu tambem quero ter um irmao programador pra mim poder ficar discutindo metodologias de desenvolvimento com ele e outras noias do genero...
|
"working code attracts people who want to code. Design documents attract people who want to talk about coding - Charles Miller"
http://rafaelsteil.com
http://twitter.com/rafaelsteil
http://www.jforum.net
http://www.flickr.com/photos/rafaelsteil |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/09/2002 23:18:39
|
urubatan
Moderador
![[Avatar]](/images/avatar/fe9fc289c3ff0af142b6d3bead98a923.jpg)
Membro desde: 21/09/2002 10:31:26
Mensagens: 2481
Localização: Porto Alegre/RS
Offline
|
da pra fazer isto aqui mesmo com a galera
perdi o inicio da conversa, mas eu utilizaria a opção mais orientada a objeto mencionada,
com um unico metodo estatico, para adicionar o texto das novas mensagens nos buffers de cada cliente.
ai sincronizaria apenas por este metodo
|
[]'s
Rodrigo Urubatan
http://www.urubatan.com.br
Melhor livro de RoR do brasil: http://livro.urubatan.com.br
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 25/09/2002 00:23:30
|
aconstantino
Virtual Machine Man
![[Avatar]](/images/avatar/3295c76acbf4caaed33c36b1b5fc2cb1.png)
Membro desde: 14/09/2002 16:37:24
Mensagens: 698
Offline
|
Sabendo que deve ser o protocolo HTTP mas ja palpitando... :)
No meu ponto de vista a melhor forma é criar um protocolo próprio para o chat (já que o chat em discussão é um chat de grande porte) com encriptação e um servidor distribuindo para os clientes a grande idéia do servidor também é só receber conexões de uma rede local.
Ai então criando o socket poderiamos iniciar o servelet.Uma thread enviando e recebendo dados (isto configurado o timeout do socket ) caso dê timout o usuário é automaticamente desconectado da rede.
Isto por ser bom também para evitar os espertinhos que adoram fazer softwares para conexão em chats do UOL etc...
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 25/09/2002 11:27:53
|
Guilherme Silveira
Administrador
Membro desde: 14/08/2002 10:09:26
Mensagens: 1096
Localização: Sao Paulo
Offline
|
Olha gente, ja terminei o chat que vou usar de exemplo no tutorial, ele nao tem suporte pra salas mas pode ser facilmente adaptado.
Estarei escrevendo agora o tutorial e creio que na sexta terei ele pronto.
Para acessar o chat de exemplo basta incluir teu login no lugar do "SEULOGINAQUI"!
http://www.guj.com.br/servlet/br.guj.chat.ChatServlet?login=SEULOGINAQUI
Abraco
Guilherme
|
-------------------------------------------------------
Guilherme Silveirahttp://blog.caelum.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 25/09/2002 11:40:43
|
Guilherme Silveira
Administrador
Membro desde: 14/08/2002 10:09:26
Mensagens: 1096
Localização: Sao Paulo
Offline
|
nossa
o baguio loto de gente
e ta rapidissimo
|
-------------------------------------------------------
Guilherme Silveirahttp://blog.caelum.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 25/09/2002 18:08:09
|
jmprado
Entusiasta Java
![[Avatar]](/images/avatar/c8c350163d910c11c5c93.gif)
Membro desde: 18/09/2002 17:29:22
Mensagens: 16
Localização: Belo Horizonte - MG
Offline
|
java.lang.NullPointerException
quando enviei um texto para "todos" no chat
|
______________
< Java não é uma linguagem. É um paradigma. /> |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 25/09/2002 18:12:20
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
hehehe
ta dando NullPointer agora mesmo!
Gui, pode apostar que eh cosia do GarbageCollector, ou coisa dos OutputStreams que fecham depois de um tempo!
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
|
|