java实现http长连接
前提
之前看apollo源码,有讲到apollo通知服务配置变动的方式有主动通知和定时拉取的两种方式,定时拉取使用的是定时线程去做的。而主动通知,则是使用http长连接实现的。
如何实现
http长连接类似于我们在web项目的debug模式一般,我们拿到http请求,并不立刻返回,而是等待一段时间后返回,如果期间有变动,则立刻返回,如果没有变动,则返回304,另一端判断http的返回,根据返回值进行不同操作。
http请求返回后,立刻再发起一个http请求,这样子则可以实现http的长连接了。
Spring MVC的实现
Spring MVC有异步返回的DeferredResult,可以使用这个进行实现http长连接。
代码实现
/**
* @author xixingya
* @version 1.0
* @date 2020/11/13 11:44 上午
*/
@RestController
@RequestMapping("/async")
public class AsyncController {
final Map<Integer,DeferredResult> deferredResultMap = new ConcurrentReferenceHashMap();
@GetMapping("/longPolling")
public DeferredResult DeferredResultlongPolling(){
DeferredResult deferredResult=new DeferredResult(60000L);
deferredResultMap.put(deferredResult.hashCode(),deferredResult);
deferredResult.onCompletion(()->{
deferredResultMap.remove(deferredResult.hashCode());
System.err.println("还剩"+deferredResultMap.size()+"个deferredResult未响应");
});
deferredResult.onTimeout(()->{
deferredResult.setResult("304");
});
return deferredResult;
}
@GetMapping("/returnLongPollingValue")
public void returnLongPollingValue(){
for (Map.Entry<Integer, DeferredResult> resultEntry : deferredResultMap.entrySet()) {
resultEntry.getValue().setResult("qaq");
}
}
}
springboot例子
链接: 例子.
https://github.com/xixingya/longPolling