如何使用Spring启动创建事件源服务器?
这是Spring 4.2的简单实现。不要顾及线程,它的存在只是用于演示目的:
@RestController
public class AccountsRestController {
@RequestMapping("/accounts/alerts")
public SseEmitter getAccountAlertsNoPathVariable(HttpSession session) {
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
Thread t1 = new Thread(() ->{
try {
int i = 0;
// Send 10000 messages
while(++i<=10000){
Thread.sleep(1000);
System.out.println("Sending");
try{
emitter.send(new Alert((long)i, "Alert message"+i));
}catch(ClientAbortException cae){
//The client is not there anymore, we get out of the loop
i = 10000;
}
}
emitter.complete();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
return emitter;
}
我的需求是发送通知计数。只是一个整数。如果我用“emitter.send(notificationCount);”替换整个线程块这段代码运行的频率如何?我没有得到的是,如何在用户浏览器会话激活之前无限流。我应该保持一个while循环来检查用户会话并在循环中休眠吗? – Anand
如果您删除该线程,则只会发送一个事件。这就是为什么你需要一个线程来运行,直到你想要的。作为一个更清洁的替代品,您可以使用ExecutorService启动发送()消息的任务。 – codependent
要更清楚一点:您不需要检查浏览器是否处于活动状态。 'emitter.send()'会抛出一个'IOException'(Tomcat中的'ClientAbortException'),表示客户端不在那里。我已经更新了答案。 – codependent
我试着下面的代码,从@codependent的解决方案重写,以满足我的需要。它的回应。但是,在浏览器选项卡关闭时不要终止连接。它继续在服务器端运行。任何与HTTP GET有关的事情?
@RequestMapping(value = "/getNotificationCount/{userId}",method = RequestMethod.GET)
public SseEmitter getNotificationCount(@PathVariable("userId") String userId, HttpServletResponse response){
SseEmitter emitter = null;
try {
emitter = new SseEmitter();
while(true) {
try{
int count= myService.getNotificationCount(Integer.parseInt(userId));
emitter.send(count);
Thread.sleep(30 * // minutes to sleep
60 * // seconds to a minute
1000); // milliseconds to a second
}catch(ClientAbortException cae){
LOGGER.info("ClientAbortException Breaking the notification stream");
break;
}
}
//Closes the stream
emitter.complete();
} catch (Exception e) {
//Closes the stream
emitter.complete();
}
return emitter;
}
看起来没问题。看看我的示例项目:https://github.com/codependent/spring4-sse端点是/ accounts/alerts。当我关闭浏览器时会引发异常。 – codependent
@codependent发现问题。它不与代码...但是与防火墙,它正在等待连接关闭,然后才会释放数据并触发连接打开事件(只有在服务器端关闭连接后,才会触发'onopen'事件并且'onmessage'是一次性触发所有消息。感谢所有帮助。现在寻找这个选项:(http://stackoverflow.com/a/13135995/1057093 – Anand
我很高兴你找到了。祝你好运! – codependent
[春REST SSE执行]的可能的复制(http://stackoverflow.com/questions/31229015/sse-implementation-in-spring-rest) – kaliatech
那家链路无弹簧启动解决方案。它说目前没有支持。所以会请求离开这个问题。 – Anand