SSE Emitter : Manage timeouts and complete()

你。 提交于 2020-02-24 03:33:31

问题


I am writing a web app where multiple listeners(Evcentsource SSE clients JS) will be connected to my server . what i want to do is

  1. Store SSE emitter per connected listener : can be done in memory or any other means by assigning id to each client I am able to achieve this so far
  2. Now the question ; How do i send a response/event to specific client connected to my web app ? while doing this SSEEmmiters stored are either getting completed or timed out. how do i prevent this ? how do i keep sseEmmiter available open for infinite time (till client closes) and send events selectively .

回答1:


You need to set the timeout on the SseEmitter. The default timeout is rather short.

The SseEmitter timeout is in milliseconds. It is a session timeout, not affected by activity on the session.

The timeout needs to be set to the expected duration of the session, in milliseconds. So, 86400000 (or more) is entirely appropriate.




回答2:


Details about how you should set a proper timeout. 2 ways of doing this with Spring

  1. Using the SseEmitter constructor
SseEmitter emitter = new SseEmitter(15000L); // Example for 15s
  1. Using Spring property
spring.mvc.async.request-timeout: 15000

Quote from documentation

By default not set in which case the default configured in the MVC Java Config or the MVC namespace is used, or if that's not set, then the timeout depends on the default of the underlying server.




回答3:


If you want the sseEmmiter available open for infinite time, you can simply set the time out to -1L

and to send events selectively put all of sseEmmiters in a map with specific key to use it when you want to send event like i did in this code .

@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;
 }
}


来源:https://stackoverflow.com/questions/40462780/sse-emitter-manage-timeouts-and-complete

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!