Flush in asynchronous servlet does not work

1

I am studying for web certification, and I came across a problem when trying to make a chat using long pooling, but precisely in the article:

link

I noticed that my client did not get the writing, so I wrote a basic example to see if the answer was written without calling oncomplete() in the asynchronous context, but I noticed that it did not work in Chrome, locking the browser, but firefox and IE worked, so the question is:

In this code below should the customer get the answer or is there an 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 as follows:

<%@ 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 made get , but only if I give a complete, but this way I disconnect the client, and there it would that make a new get .

In the first code does not have the client list implementation, in case the first doubt worked after seting

resp.setContentType("text/html");

But now, in the code that I'm really implementing the chat, I'm having this problem, maybe I have to give ctx.complete() , but I think it's strange to have to re-chat every time and the Git source does not have complete .

    
asked by anonymous 07.04.2015 / 05:03

0 answers