SSE发射器:管理超时并完成()

时间:2016-11-07 10:20:56

标签: java spring server-sent-events eventemitter

我正在编写一个Web应用程序,其中多个侦听器(Evcentsource SSE客户端JS)将连接到我的服务器。我想做的是

  1. 每个连接的侦听器存储SSE发射器:可以通过为每个客户端分配id到目前为止在内存或任何其他方式完成此操作
  2. 现在的问题;如何将响应/事件发送到连接到我的Web应用程序的特定客户端?执行此操作时,存储的SSEEmmiters要么已完成,要么已超时。我该如何防止这种情况?我如何让sseEmmiter保持无限时间(直到客户关闭)并有选择地发送事件。

4 个答案:

答案 0 :(得分:4)

您需要在SseEmitter上设置超时。默认超时时间很短。

SseEmitter timeout以毫秒为单位。这是会话超时,不受会话活动的影响。

需要将超时设置为会话的预期持续时间(以毫秒为单位)。所以,86400000(或更多)是完全合适的。

答案 1 :(得分:3)

如果您希望sseEmmiter可以无限期打开,则只需将超时设置为-1L

并有选择地发送事件,将所有sseEmitmiters放置在具有特定键的地图中,以便在您要发送事件时使用它 就像我在这段代码中所做的一样。

@Controller
@RequestMapping(path = "api/person")
public class PersonController {

 @Autowired
 private PersonRepository personRepository;
 private Map<String, SseEmitter> onPersonAddedSseEmitters = new ConcurrentHashMap<>();

 @PostMapping(path = "/add")
 public @ResponseBody
 String addPerson(@RequestBody Person person) {
   person.setId(new Random().nextLong());
   personRepository.save(person);
   onPersonAddedSseEmitters.forEach((key, sseEmitter) -> {
     try {
       if (person.getName().startsWith(key.split("-")[0])) {
         sseEmitter.send(person);
       }
     } catch (Exception ignored) {
       sseEmitter.complete();
       onPersonAddedSseEmitters.remove(key);
     }
   });
   return "Saved";
 }

 @GetMapping(path = "/onPersonAdded/{prefix}")
 public SseEmitter onPersonAdded(@PathVariable String prefix) {
   SseEmitter sseEmitter = new SseEmitter(-1L);
   onPersonAddedSseEmitters.put(prefix + "-" + new Random().nextLong(), sseEmitter);
   return sseEmitter;
 }
}

答案 2 :(得分:2)

有关如何设置正确超时的详细信息。使用Spring的两种方法

  1. 使用SseEmitter构造函数
  2. SseEmitter emitter = new SseEmitter(15000L); // Example for 15s
    
    1. 使用Spring属性
    2. spring.mvc.async.request-timeout: 15000
      

      从文档中引用

        

      默认情况下,不设置MVC中配置的默认值   使用Java Config或MVC命名空间,或者如果未设置,则使用   超时取决于底层服务器的默认值。

答案 3 :(得分:0)

为解决超时问题,我们使用Long.MAX_VALUE作为超时,并且效果很好。