VRaptor - Ajax reverso

Pessoal, alguém já conseguiu fazer alguma implementação para conseguir o recurso de ajax reverso com vraptor?

Gosto bastante do vraptor mas não consigo largar o DWR por conta do recurso de ajax reverso…

Alguma sugestão, ideia?..

Valeu.

ajax reverso por polling ou por comet?

comet! :?

a gente acabou não implementando comet no VRaptor pq o suporte dos servidores e (era) meio zuado em java…

até tem um AsyncContext no servlet 3 que dá pra usar, mas não funciona com filtros (pelo menos no tomcat)

muito ruim trocar pra polling por enquanto?

quer contribuir pro vraptor, e ajudar a gente a implementar isso?

Confesso que sou bem noobzin em como fazer isso, mas tava até querendo “abrir” o código do dwr pra entender direitinho como ele faz isso pra ver se tenho alguma ideia de fazer isso no vraptor…

Acho que polling não rola pro que preciso, porque o meu servidor precisa fazer umas consultas “fatiadas” e ir enviando aos poucos assim que cada “fatia” estiver pronta…

Como falei, vou tentar dar uma estudada no código do DWR e no código do VRaptor… de repente sai alguma ideia e se surgir algo eu compartilho depois…

Obrigado!

Eu fiquei bem interessado no AJAX reverso depois que eu vi esse seu post…

Eu começei a dar uma olhada no tipo comet.

Pelo que eu pude ver, ele nada mais é que um pooling que demora para terminar a requisição…

public void requisicao(){ Boolean retorna = false; Object obj = null; while (!retorna){ // Verifica se houve mudanças // seta retorna com true // seta obj try { Thread.sleep(500L); } catch (InterruptedException e) { e.printStackTrace(); } } result.use(Results.json()).from(obj).serialize(); }
Assim, a requisição irá demorar o tempo que for necessário, desde que aja alguma mudança…
E, assim que o ajax terminar a requisição, você pega os dados necessários e já faz outra requisição para o método requisicao();

Quando tiver outra alteração, o ciclo se repetirá.

Então, eu comecei por esse caminho também, mas depois vi algumas limitações e problemas que não soube resolver…

Por exemplo,

  1. Se o usuário troca de página ou vai fazer qualquer outra coisa, seu método vai continuar rodando e dando Thread.sleep sem mais necessidade, visto que o usuário já não precisa mais dos dados… como interromper aquela thread que está se repetindo?

  2. Será que simplesmente dar Thread.sleep não consome demais o servidor? Será que aumentar o tempo do sleep() resolve? Enfim, como seria legal para otimizar essa solução de forma a não sobrecarregar esse long polling?

  3. O DWR tem um esquema bacana de determinar os navegadores que ele vai enviar uma determinada informação, algo como
    Browser.withAllSessions(Runnable) ou
    Browser.withSessionFilter(SessionFilter, Runnable)
    No DWR existe uma implementação para guardar uma referência de cada usuário em cada página, o que te permite ter um controle mt bacana de quais usuários devem receber determinada informação pelo ajax reverso.

Valeu! :slight_smile:

não façam isso na mão… os servidores mais novos já tem recursos pra isso…

se vc deixar uma requisição parada com um while(…) Thread.sleep(), vc tá consumindo uma thread do servidor a toa…

vc precisa usar o AsyncContext (servlet 3) que deixa o cara esperando, mas não consome a thread do servidor.

E o que costumo fazer com DWR que eu queria fazer com vraptor, é algo assim:

while (Object parteInformacao = pegoAlgoDeAlgumLugar() != null) {
  envioParteDaInformacaoProUsuario(parteInformacao);
}

vc pode fazer isso, mas vai ficar uma thread do servidor parada nessa requisição… consequentemente vc não vai conseguir ter mtos usuários simultâneos (limitado pelo número de threads configuradas no servidor, por padrão é uns 50)

daí se chegar o 51º usuário, ele não vai conseguir acessar o sistema.

Teve um exemplo que eu encontrei nesse site:
https://blogs.oracle.com/enterprisetechtips/entry/asynchronous_support_in_servlet_3

[code]@WebServlet("/foo" asyncSupported=true)
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) {

AsyncContext aCtx = request.startAsync(req, res);
ScheduledThreadPoolExecutor executor = new ThreadPoolExecutor(10);
executor.execute(new AsyncWebService(aCtx));
}
}

public class AsyncWebService implements Runnable {
AsyncContext ctx;
public AsyncWebService(AsyncContext ctx) {
this.ctx = ctx;
}
public void run() {
// Invoke web service and save result in request attribute
// Dispatch the request to render the result to a JSP.
ctx.dispatch("/render.jsp");
}
}[/code]
Mas eu não entendi como ele vai ficar fazendo aquela verificação se o dado “está pronto”…

a idéia é vc fazer dentro do método run… se eu não me engano o ctx. tem um método pra esperar um tempo… um sleep da vida:

while(!dado.estaPronto()) {
   ctx.sleep(...);
}

Acho que para resolver o problema do usuário sair da página, é só você enviar uma requisição ajax no $(window).unload(function() {/Chamada Ajax/});
Essa requisição vai para um outro método. Esse método pode setar uma variável estática que define se foi cancelado, ai o outro método que está rodando verifica essa variável também e pula fora se ela estiver “ativa”…

Para resolver o problema do usuário e ver quem quer o que, é só criar uma classe @SessionScoped e receber no construtor da classe… assim você ja sabe quem é o usuário.

a gente geralmente define um timeout pequeno pra essas requests longas… tipo 30s ou 1 min, daí qdo terminar o request a gente refaz no JS… daí evita o problema do cara sair da página e ficar um cara preso

então o timeout vai obrigar um retorno mesmo se nada for encontrado?

Assim é possível saber se ele saiu ou não…

então, meio que tanto faz… é um timeout que vc sabe que vai acontecer toda hora…

tipo vc faz algo assim no js:

while(true) {
   //faz o request
}

e no servidor vc cria aquele runnable que depois de 30 s (por exemplo) não retorna nada e fecha o request.

O atmosphere tenta resolver isto de uma forma mais homogênea.

https://github.com/Atmosphere/atmosphere

Estou ainda avaliando como ele funciona.

Lucas, será q isso ajudaria a inclusão do suporte a comet no vraptor?

possível…

quer fazer o teste e contar o que aconteceu?

se precisar de ajuda dá um toque

Nunca tinha ouvido falar do atmosphere até o início da semana quando me deparei com a necessidade de comet sobre Vraptor.

Parece ser bem completo e está recheado de exemplos.

Nunca tinha ouvido falar.

Aviso se tiver novidades.

Lucas,

neste endereço aqui temos um exemplo de implementação com Spring, porem utiliza servlets, é necessário mesmo, tem como fazer sem servlet?

https://github.com/Atmosphere/atmosphere-extensions/tree/master/spring/samples/spring-websocket

abs.