发送服务器发送事件的Servlet更新比编码更快

时间:2014-10-01 11:07:43

标签: java jsp servlets server-sent-events

代码结构:

  • 服务器:Java Servlet
  • 客户端:简单JSP
  • 通信:服务器每1秒发送一次事件

这是问题所在。

我的代码需要服务器每隔一秒向客户端发送更新,如上所述。 因此,我在servlet代码中添加了一个休眠为1000毫秒的while循环,如下所示。观察到以下奇怪的行为:

  1. 当服务器向客户端发送更新,而客户端窗口错误关闭时,服务器不会停止发送更新它继续发送数据。
  2. 重新打开客户端后,它会更快地发送数据(几乎是两倍)。例如,服务器仅需25-30秒即可发送60秒的更新(60次更新)。服务器不仅为这一轮更新发送更快的更新,而且还为任何后续更新发送更快的更新。

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res)
            throws IOException, ServletException {
        PrintWriter writer = null;
        try{
             res.setContentType("text/event-stream;charset=UTF-8");
             res.setHeader("Cache-Control", "no-cache,no-store,max-age=0,max-stale=0");
             res.setHeader("Connection", "keep-alive");       
             writer = res.getWriter();
             while(true){
                    getDatafromDB(writer);
                    // send SSE
                    writer.write("data: \n\n");
                    writer.flush();
                 try {
    
                        Thread.sleep(1000);
                       } catch (InterruptedException iex) {
                        System.out.println("ECGDataUpdater::doGet(): " + iex.toString());
                            iex.printStackTrace();
                       }
             }
    
        }catch(Exception ex){
            System.out.println("ECGDataUpdater:doGet :: " + ex.toString());
            ex.printStackTrace();
        }
        finally{
            try{
                cxt.close();
            }catch(Exception ex){
                System.out.println("ECGDataUpdater:doGet:finally :: " + ex.toString());
                ex.printStackTrace();
            }
                writer.close();
        }
    }
    
  3. 另一方面,当servlet代码是服务器发送事件代码的默认值时,服务器每隔3秒发送一次更新,并且不涉及while循环,服务器的行为与预期一致。这是::

    1. 当服务器仍在发送更新时关闭客户端窗口时,服务器会停止发送更新。服务器在重新打开客户端窗口时恢复发送更新。
    2. 一旦窗口重新打开,数据更新到客户端的速率是统一的:单次更新为3秒,60次更新为180秒。
    3. 更新间隔为3秒的java的默认Server Sent Events代码如下所示:

         @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
              PrintWriter writer = null;
              try{
                   res.setContentType("text/event-stream;charset=UTF-8");
                   res.setHeader("Cache-Control", "no-cache,no-store,max-age=0,max-stale=0");
                   res.setHeader("Connection", "keep-alive");       
                   writer = res.getWriter();
      
                   getDatafromDB(writer);
                   writer.write("data: \n\n");
                   writer.flush();
      
              }catch(Exception ex){
                  System.out.println("ECGDataUpdater:doGet :: " + ex.toString());
                  ex.printStackTrace();
              }
              finally{
                  try{
                      cxt.close();
                  }catch(Exception ex){
                      ex.printStackTrace();
                  }
                      writer.close();
              }
          }
      

      此服务器行为非常出乎意料。我写服务器端代码错了吗?我已经环顾了很多,只找到while循环方法来修改服务器更新间隔。还有其他方法我错过了吗?我怎样才能克服上述问题呢?

      提前感谢您的帮助。

0 个答案:

没有答案