eventSource 每次都会触发open 、error事件

前台代码:
if (window.EventSource) {
console.log("Event source available");
var source = new EventSource("${ctx}"+"/sseMsg");

    source.addEventListener('message', function(e) {
        console.log(e.data);
        $.pCommon.message(e.data);

        //source.close(); // close connection, otherwisse browser will request the server constantly
    });
    source.addEventListener('open', function(e) {
        console.log("Connection was opened.");
    }, false);

    source.addEventListener('error', function(e) {
        console.log(e);
        /* if (e.readyState == EventSource.CLOSED) {
            console.log("Connection was closed.");
        } else {
            console.log(e.readyState);
        } */

    }, false);

 } else {
        console.log("服务器不支持EvenSource对象");
}

后台代码:
public class SseServlet extends HttpServlet

{
/**
* serialVersionUID:TODO(用一句话描述这个变量表示什么).
*
* @since JDK 1.6
*/
private static final long serialVersionUID = 1L;

public void doPost(HttpServletRequest request, HttpServletResponse response)
{
    try
    {
        //最后一次接收到的事件的标识符
        String last = request.getHeader("Last-Event-ID");
        String retry = "retry:"+10000+"\n";//浏览器默认的是,如果服务器端三秒内没有发送任何信息,则开始重连。服务器端可以用retry头信息,指定通信的最大间隔时间。
        response.setContentType("text/event-stream"); // SSE header
        response.setCharacterEncoding("utf-8");
        response.setHeader("Cache-Control","no-cache");
        response.setHeader("Connection","keep-alive");

        // 从消息队列中获取app、web消息推送对应操作人
        //在全局范围内使用LinkedBlockingQueue对象,当有需要发送的数据时,将数据放到队列中,然后在循环中调用poll方法即可
        // do something
        PrintWriter writer = response.getWriter();
        //多行数据的话每一行前面都要data:之后加上一个\n,最后一行是两个\n。           
        //以冒号开头的行,表示注释。通常,服务器每隔一段时间就会向浏览器发送一个注释,保持连接不中断。
        writer.write(retry);
        for(int i=0; i<10; i++) {

            writer.write("data: "+ System.currentTimeMillis() +"\n\n");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        writer.close();
    } catch (Exception e)
    {
        e.printStackTrace();
    }
}

public void doGet(HttpServletRequest request, HttpServletResponse response)
{
    doPost(request, response);
}

}

运行结果:每次触发open、error事件,导致每次断开重连,请问是哪里写的有问题,导致触发onerror事件
图片说明

求答案

是这样的,你数据发送完了之后,并没有一直保持这个连接,浏览器检测到断连了,就触发了EventSource的重连机制。
解决方法有两个 1.

source.addEventListener('error', function(e) {
        console.log(e);
        source.close();
        /* if (e.readyState == EventSource.CLOSED) {
            console.log("Connection was closed.");
        } else {
            console.log(e.readyState);
        } */
 
    }, false);

该方法需要后端主动调用close这个event.
2.source.addEventListener('close', function(e) {
        source.close();
        /* if (e.readyState == EventSource.CLOSED) {
            console.log("Connection was closed.");
        } else {
            console.log(e.readyState);
        } */
    }, false);

通过以上任意一个方法,都可以保证连接发送之后不会重连。