简体   繁体   English

Play Framework SSE结束分块响应

[英]Play Framework SSE Closing Chunked Response

I'm trying to implement Server-Side Events server in Play Framework 1.2.5 我正在尝试在Play Framework 1.2.5中实现服务器端事件服务器

How can I know if the client called EventSource.close() (or closed its browser window, for example)? 我如何知道客户端是否调用EventSource.close() (或关闭其浏览器窗口)? This is a simplified piece of server code I'm using: 这是我正在使用的简化的服务器代码:

public class SSE extends Controller {

  public static void updater() {
    response.contentType = "text/event-stream";
    response.encoding = "UTF-8";
    response.status = 200;
    response.chunked = true;

    while (true) {
      Promise<String> promise = Producer.getNextMessage();
      String msg = await(promise);
      response.writeChunk("data: " + msg + "\n\n");
    }
  }
}

Producer should deal with queuing, Promise objects, and produce the output, but I should know when to stop it (filling its queue). Producer应该处理队列, Promise对象并产生输出,但是我应该知道何时停止它(填充其队列)。 I would expect some exception thrown by response.writeChunk() if the output stream is closed, but there's no any. 我希望如果输出流关闭,则response.writeChunk()会抛出一些异常,但是没有任何异常。

There's a similar example that does not deal with SSE, but only chunks instead, at http://www.playframework.com/documentation/1.2.5/asynchronous#HTTPresponsestreaming http://www.playframework.com/documentation/1.2.5/asynchronous#HTTPresponsestreaming ,有一个类似的示例不涉及SSE,而仅涉及块

Since play.mvc.Controller doesn't let me know if the output stream is closed during the execution, I solved the problem through the Producer itself: 由于play.mvc.Controller不会让我知道执行过程中输出流是否关闭,因此我通过Producer本身解决了该问题:

  1. In Producer.getNextMessage() , the current time is remembered. Producer.getNextMessage() ,会记住当前时间。
  2. In Producer.putMessage(String) , the time since last 'get' is checked. Producer.putMessage(String) ,检查自上次“获取”以来的时间。 If it's greater than some threshold, we can consider that SSE channel is closed. 如果大于某个阈值,则可以认为SSE通道已关闭。

There's also this class play.libs.F.EventStream which can be useful within the Producer . 还有一个类play.libs.F.EventStreamProducer很有用。

Plus, Producer might not be the right name here, since it's more of a dispatching queue... 另外, Producer在这里可能不是正确的名称,因为它更像是一个调度队列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM