java使用DeferredResult实现http长连接

java实现http长连接

  • 前提
  • 如何实现
  • Spring MVC的实现
  • 代码实现
  • springboot例子

前提

之前看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

你可能感兴趣的:(java,http,开发语言)