长轮询AsyncContextServer
上代码基础是使用Servlet3的request.startAsync开启异步任务,然后可以将这个请求的request,response封装后得到AsyncContext然后存储,然后另外的请求去对这个asyncContext做处理然后主动返回数据(调用complete方法)写了个工具类如下
@Component public class AsyncContextServer implements InitializingBean, DisposableBean { private AsyncContextServer(){ } private static Long delayTime = 30000L; @Override public void afterPropertiesSet() { } @Override public void destroy() { dataIdContext.clear(); } @Data private static class AsyncTask { private AsyncContext asyncContext; private boolean timeout; public AsyncTask (AsyncContext asyncContext,boolean timeout){ this.asyncContext = asyncContext; this.timeout = timeout; } } private static ConcurrentHashMap<String, AsyncTask> dataIdContext = new ConcurrentHashMap<>(); private static ThreadFactory threadFactory = r -> { Thread thread = new Thread(r); thread.setName(String.format("longPolling-timeout-checker-%s", LocalDateTime.now())); return thread; }; private static ScheduledExecutorService timeoutChecker = new ScheduledThreadPoolExecutor(3,threadFactory); public static void addAsyncTask(String dataId, HttpServletRequest request, HttpServletResponse response){ AsyncContext asyncContext = request.startAsync(request,response); AsyncTask asyncTask = new AsyncTask(asyncContext,true); dataIdContext.put(dataId,asyncTask); timeoutChecker.schedule(()->{ if (asyncTask.isTimeout()){ dataIdContext.remove(dataId,asyncTask); response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); asyncTask.getAsyncContext().complete(); } },delayTime, TimeUnit.MILLISECONDS); } public static void publishTask(String dataId,Object value) throws IOException { AsyncTask asyncTask = dataIdContext.get(dataId); dataIdContext.remove(dataId); asyncTask.setTimeout(false); HttpServletResponse response = (HttpServletResponse) asyncTask.getAsyncContext().getResponse(); response.setStatus(HttpServletResponse.SC_OK); response.getWriter().println(JSON.toJSONString(value)); asyncTask.getAsyncContext().complete(); } public static HttpServletResponse getResponse(String dataId){ AsyncTask asyncTask = dataIdContext.get(dataId); HttpServletResponse response = (HttpServletResponse) asyncTask.getAsyncContext().getResponse(); return response; } }

浙公网安备 33010602011771号