首页
学习
活动
专区
圈层
工具
发布

Java聊天
EN

Stack Overflow用户
提问于 2015-04-10 13:09:10
回答 1查看 317关注 0票数 0

我试图做一个简单的聊天,用户连接到服务器发送一条消息,而其他用户收到它。

这是我的html:

代码语言:javascript
复制
 <%@page contentType="text/html" pageEncoding="UTF-8"%>
 <!DOCTYPE html>
 <html>
   <body>
     <script>
       function setupEventSource() {
         var output = document.getElementById("output");
         if (typeof(EventSource) !== "undefined") {
           var msg = document.getElementById("textID").value;
           var source = new EventSource("TestServlet?msg=" + msg);
           source.onmessage = function(event) {
             output.innerHTML += event.data + "<br>";
           };

           source.addEventListener('close', function(event) {
             alert("Source closed!");
             source.close();
             }, false);
         } else {
           output.innerHTML = "Sorry, Server-Sent Event is not supported in your browser";
         }
         return false;
       }
     </script>

     <h2>Simple SSE Echo Demo</h2>
     <div>
       <input type="text" id="textID" name="message" value="Hello World">
       <input type="button" id="sendID" value="Send" onclick="setupEventSource()"/>
     </div>
     <hr/>
     <div id="output"></div>
   </body>
 </html>

而且在servlets中也是这样的:

代码语言:javascript
复制
    // set content type
    response.setContentType("text/event-stream");
    response.setCharacterEncoding("UTF-8");

    String msg = request.getParameter("msg");

    PrintWriter writer = response.getWriter();

    // send SSE
    writer.write("data: " + msg + "\n\n");
    writer.write("event: close\n");
    writer.flush();

有几件事我不明白:如果我不发送一个event: close,浏览器将继续垃圾邮件每3秒,这是为什么?我试图通过关闭EventSource来避免这种情况,但这是正确的吗?一旦EventSource关闭,您就不能像刚刚关闭一样打开它,对吗?

我也希望所有的“连接的客户”都收到消息,但这种情况不会发生,难道data:不是应该发送到所有客户端吗?

我尝试过使用chrome和firefox并发送消息,我注意到了一些关于火狐的东西:这条消息每隔6秒就会发出一次垃圾邮件,而我在每条消息之后发送event: close

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-10 15:21:21

您是否关闭servlet中的请求?服务器上的SSE请求需要以不同的方式处理:

标准Servlet:

  1. 来自客户端的请求
  2. 服务器创建响应。
  3. 服务器将响应发送回客户端。
  4. 服务器关闭连接。

对于SSE,典型的流略有不同。首先,您通常需要工作流、处理连接注册的servlet工作流和处理向已注册侦听器发送事件的事件工作流。

Servlet工作流:

  1. 来自客户端的请求(带有类型的事件流)
  2. 服务器将连接缓存在内存中。
  3. 服务器不关闭连接。

事件工作流:

  1. 发生了触发事件的事情
  2. 服务器抓取连接的缓存。
  3. 对于每个仍处于打开状态的连接,服务器将写入该事件。

我的猜测是,当您得到一个事件流请求时,您正在写出当时的事件,然后关闭连接。这会触发客户端上的EventSource认为它被断开或错误地关闭,3秒后,它试图重新注册到服务器,然后整个进程再次发生。

还有一点要注意。如果您正在使用servlet,那么您几乎肯定需要使用异步servlets,否则,您将为每个连接的客户端提供一个开放线程。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29562295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档