Instant Messaging

Pessoal,

não sei se ‘Instant Messaging’ é um bom título mas aki vai.

Estou dando manutenção em um sistema Web usando Struts, que possui uma página que a cada 30 segundos faz um refresh para chamar uma action que vaz um acesso à base e mostra os dados cadastrados.

Esse lance de fazer refresh a cada 30 segundos é um pouco ‘feio’.
Por tanto decidi mudar isso! Para o controle do lado server, fiz um servlet e no objeto ServletHttpResponse eu faço um flush sempre que determinada condição é satisfeita.

Para o controle do lado client eu tentei manipular os dados recebidos com o objeto XMLHttpRequest checando o readyState==3 (Estado Iterativo).

Segue abaixo o Servlet MainServlet.java:

package servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @version 	1.0
 * @author
 */
public class MainServlet extends HttpServlet {

	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doService(req, resp);
	}

	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doService(req, resp);
	}

	public void doService(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
				 
		PrintWriter out = resp.getWriter();
		String resultado = "";
		
		

		try {
			for (int i = 0; i <= 4; i++) {
				
				resultado = i + " - Teste<br>";
				out.println(resultado);		
				resp.flushBuffer();
				
				Thread.sleep(1000);								
			}
			
		} catch (InterruptedException e) {			
			e.printStackTrace();
		}
		System.out.println("fim");

	}

}

E agora a JSP index.jsp que foi usada:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<HTML>
<HEAD>
<%@ page 
language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"
%>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="IBM WebSphere Studio">
<META http-equiv="Content-Style-Type" content="text/css">
<LINK href="../theme/Master.css" rel="stylesheet" type="text/css">

<script language="javascript">
var xmlhttp=false;

if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
	try {
		xmlhttp = new XMLHttpRequest();
	} catch (e) {
		xmlhttp=false;
	}
}

if (!xmlhttp && window.createRequest) {
	try {
		xmlhttp = window.createRequest();
	} catch (e) {
		xmlhttp=false;
	}
}

function request(){
	xmlhttp.open("post", "/im-web/MainServlet", true);
	xmlhttp.onreadystatechange = stateChange;
	xmlhttp.send(null)
}

function stateChange(){
	//alert(xmlhttp.readyState);
	if (xmlhttp.readyState==3) {
		document.getElementById("estado").innerHTML = "";
		document.getElementById("resposta").innerHTML = xmlhttp.responseText;
	} else {
		document.getElementById("estado").innerHTML = "Carregando";
		document.getElementById("resposta").innerHTML = "";
	}
}

</script>

<TITLE>index.jsp</TITLE>
</HEAD>
<BODY>



<TABLE border="0">
	<TBODY>
		<TR>
			<TD width="352" align="center"><FONT color="#0000cc"> Área de mensagens </FONT></TD>
		</TR>
		<TR>
			<TD width="352" height="75" style="border: 1px dashed #0000CC; overflow: scroll;">&nbsp;
			<div id="resposta"></div>
			</TD>
		</TR>
		<TR>
			<TD width="352" onclick="request()" onmouseover="this.style.cursor='pointer'" align="right">
			<FONT color="#0000cc"> Submeter </FONT></TD>
		</TR>		
	</TBODY>
</TABLE>

<div id="estado">
</div>

</BODY>
</HTML>

[color=#CC0000]
Porém não está dando certo! Estou recebendo a mensagem de erro javascript: ‘Os dados necessários para concluir esta operação ainda não estão disponíveis’.
[/color]

Alguem sabe como fazer isso funcioar?

Alguem já passou por algo semelhante? Tem outra solução?

A principio não tem como pegar os dados com o readyState = 3.
Quero fazer um “messenger” e me deparei com o mesmo problema se fosse utilizar o ajax.
Solução que vou implementar mais adiante vai ser fazer um esquema para o javascript buscar no servidor de tempos em tempos, se tiver alguma coisa ele joga na tela, se não ele espera mais um tempo.

Defendendo essa minha solução, do modo que tu ta fazendo a servlet(parecida com a minha) ela vai executar mesmo que o usuario não esteja mais na pagina, se a servlet cai em loop infinito ela vai ficar no metodo GET ou POST para sempre :shock:
Fazendo com o javascript, ele busca de tempos em tempos e se o cara sai a servlet não vai mais executar.

Se tiver ideia posta ai que eu rpetendo aproveitar tambem!

Gostei da sua idéia. Parece uma boa alternativa. Quais obejetos javascript vc vai usar?

A respeito do readyState = 3 eu até consegui fazer funcionar, mas só para o firefox, no ie >= 6 eu testei e não funcionou e como o padrão aqui na empresa é ie 6 então a solução não vale, o que é uma pena :frowning: . Chega até dar raiva!!! :x No firefox funcionou direitinho!!! Alguém sabe onde eu encontro uma referência javascript completa para o ie 6?

Pode ser que exista algum outro atributo que torne a solução possível! :?

Depende. A hora que o usuário sair da pagina o socket cliente se fecha, portanto, o Servlet vai gerar uma IOException na hora do

out.println(resultado); resp.flushBuffer();
Dessa maneira o método não vai ficar em um loop infinito.
+/- assim:

try {
     for(;;;) {
         out.println(resultado);		
         resp.flushBuffer();
     }
} catch (IOException e) {
     // usuario saiu
}