微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用HTML5 Server事件和Java Servlet时如何防止net :: ERR_INCOMPLETE_CHUNKED_ENCODING?

我刚开始玩服务器事件,我遇到了一个我想了解的chrome错误信息.我快速搜索网页但没有找到解释所以我想我可能会做一些非常错误的事情.

在服务器端,我有一个简单的servlet接受请求并创建一个虚拟事件创建者任务:

private Executor executor = Executors.newSingleThreadExecutor();

public void doGet(final HttpServletRequest request,final HttpServletResponse response)
{
  final AsyncContext asynCtx = request.startAsync(request,response);

  response.setHeader("Cache-Control","no-cache");
  response.setContentType("text/event-stream");
  response.setCharacterEncoding("utf-8");

  executor.execute(() -> {
    boolean run = true;
    try
    {
      while (run)
      {
        final ServletResponse resp = asynCtx.getResponse();
        run = resp != null;

        if (resp != null)
        {
          System.out.println("pushing a server event.");
          final PrintWriter writer = asynCtx.getResponse().getWriter();
          writer.println("data: {time: " + System.currentTimeMillis() + "}\n");
          writer.flush();
        }
        else
        {
          System.out.println("stopping beeper,no response object available anymore.");
          break; // do not run anymore,we got no response
        }

        Thread.sleep(2000);
      }
    }
    catch (final Exception e)
    {
      e.printstacktrace();
    }
  });

}

在客户端我简单地说:

$(document).ready(function ()
{

   var source = new EventSource("/events");
   source.onmessage = function (event)
   {
     console.log("received event: " + JSON.stringify(event));
     document.getElementById("eventContainer").innerHTML += event.data + "<br/>";
   };

   console.log("start to receive events...")
});

当我加载HTML文件时,它工作正常,事件被接收并写入控制台.但是30秒后我收到一条错误消息:

GET [HttpOfLocalhost] / events net :: ERR_INCOMPLETE_CHUNKED_ENCODING

为什么?

请求被杀死并立即启动一个新的,所以它不会杀死应用程序,但控制台上的错误消息并不好.

我的开发者控制台截图:

请求/ resposne详细信息:

时间,这表明它总是在30秒后发生:

谢谢!

解决方法

好吧,所以我不能停滞不前,仔细看看发生了什么.

AsyncContext对象具有setTimeout(…)方法.认情况下,我的tomcat版本(Tomcat嵌入式8)的值设置为30,000毫秒(30秒).这正是我在chrome控制台中遇到net :: ERR_INCOMPLETE_CHUNKED_ENCODING错误后的持续时间.

我检查使用:

System.out.println("Current Timeout is: " + asynCtx.getTimeout() + " ms");

显示

Current Timeout is: 30000 ms

所以为了避免net:ERR消息,有人可以将超时设置为0.但是比事件线程永远运行(不幸的是).
我使用的另一种解决方案是将AsyncListener添加AsyncContext并在onTimeout()方法调用complete()方法.

来自complete()方法api文档

Completes the asynchronous operation that was started on the request
that was used to initialze this AsyncContext,closing the response
that was used to initialize this AsyncContext. Any listeners of type
AsyncListener that were registered with the ServletRequest for which
this AsyncContext was created will be invoked at their onComplete
method.

我的听众的源代码

asynCtx.addListener(new AsyncListener()
{
  @Override
  public void onComplete(AsyncEvent asyncEvent) throws IOException
  {
    System.out.println("onComplete(...)");
  }

  @Override
  public void onTimeout(AsyncEvent asyncEvent) throws IOException
  {
    // this will close the request and the context gracefully
    // and the net:ERR is gone.
    asyncEvent.getAsyncContext().complete();
    System.out.println("onTimeout(...)");
  }

  @Override
  public void onError(AsyncEvent asyncEvent) throws IOException
  {
    System.out.println("onError(...)");
  }

  @Override
  public void onStartAsync(AsyncEvent asyncEvent) throws IOException
  {
    System.out.println("onStart(...)");
  }
});

是的,这是由于缺乏知识.我希望这对某人有帮助.

原文地址:https://www.jb51.cc/html5/168456.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。