1
I am studying for web certification, and came across a problem while trying to make a chat using long pooling, but precisely in the article:
http://blog.caelum.com.br/javaee-6-contexto-assincrono-das-servlets-para-o-ajax-push/
I noticed that my client was not getting writing, so I wrote a basic example to see if the answer was written without the oncomplete()
in asynchronous context, but I noticed that it didn’t work in Chrome by locking the browser, but in firefox and IE it worked, so the question is:
In this code below the customer should get the answer or there is some error on my part?
package br.com.claudemir.livroCert;
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
@WebServlet(asyncSupported=true,urlPatterns={"/MyServlet"})
public class MyServlet extends GenericServlet {
private static final long serialVersionUID = 1L;
public MyServlet() {
super();
}
@Override
public void service(ServletRequest req, ServletResponse resp)
throws ServletException, IOException {
AsyncContext ac = req.startAsync();
ac.setTimeout(0);
MyAsincTask t = new MyAsincTask(ac);
ac.start(t);
}
}
Task
package br.com.claudemir.livroCert;
import java.io.IOException;
public class MyAsincTask implements Runnable {
private javax.servlet.AsyncContext context;
public MyAsincTask(javax.servlet.AsyncContext context) {
this.context = context;
}
@Override
public void run() {
try {
Thread.sleep(3000);
javax.servlet.ServletResponse resp = context.getResponse();
resp.getWriter().println("oim");
resp.getWriter().flush();
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
}
My code is this::
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="jquery-2.1.3.js"></script>
<script type="text/javascript" src="jquery.tmpl.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#btn_enviar").click(function(event) {
event.preventDefault();
$.ajax({
url: 'subscribe',
data: '{}',
type: 'GET',
success: function(data){
alert("resposta server");
}
});
});
$("#btn_postar").click(function(event) {
event.preventDefault();
$.ajax({
url: 'subscribe',
data: '{}',
type: 'POST',
success: function(data){
alert("post mensagem");
}
});
});
});
</script>
</head>
<body>
<form>
Entrar no Chat:<br />
<input type="button" id="btn_enviar" value="entrar" /></br>
<input type="button" id="btn_postar" value="postar" /></br>
<input type="button" id="btn_postar_simples" value="postar simples" /></br>
</form>
</body>
</html>
Servlet:
package br.com.claudemir;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = { "/subscribe" }, asyncSupported = true, loadOnStartup = 1)
public class ChatServlet extends HttpServlet {
private Queue<AsyncContext> clients = new ConcurrentLinkedQueue<AsyncContext>();
private BlockingQueue<String> messages = new LinkedBlockingQueue<String>();
private AtomicInteger contador = new AtomicInteger();
private AtomicInteger clientes = new AtomicInteger();
@Override
public void init() throws ServletException {
final ExecutorService executors = Executors.newCachedThreadPool();
Executors.newSingleThreadExecutor().execute(new Runnable() {
public void run() {
while (true) {
try {
final String message = messages.take();
for (final AsyncContext ctx : clients) {
executors.execute(new Runnable() {
public void run() {
try {
PrintWriter writer = ctx.getResponse()
.getWriter();
System.out.println(message);
writer.println(message);
writer.flush();
//ctx.complete();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
// Set to expire far in the past.
resp.setHeader("Expires", "Sat, 6 May 1995 12:00:00 GMT");
// Set standard HTTP/1.1 no-cache headers.
resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
// Set IE extended HTTP/1.1 no-cache headers (use addHeader).
resp.addHeader("Cache-Control", "post-check=0, pre-check=0");
// Set standard HTTP/1.0 no-cache header.
resp.setHeader("Pragma", "no-cache");
AsyncContext ctx = req.startAsync();
ctx.setTimeout(3000000);
clients.add(ctx);
System.out.println("novo cliente. id: " + clientes.incrementAndGet());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
System.out.println("enviando mensagem para " + clientes + " clientes");
messages.add(String.format("mensagem número %d %n", contador.incrementAndGet()));
}
}
insira o código aqui
This client was made to test the flush if I do ctx.complete
, the writing happens in all those who did get
, but only if I give a complete, but this way I disconnect the client, and then I would have to make a new get
.
In the first code has no client list implementation, in case the first doubt worked after setar
resp.setContentType("text/html");
But now, in the code that I’m actually implementing from the chat, I’m having this problem, I might actually have to give the ctx.complete()
, but I find it strange to have to re-enter the chat every time and the Git source does not have the complete
.
Claudemir, welcome to [en.so]! There seems to be no problem with its implementation. You could post the client code that runs in the browser?
– utluiz