长轮询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;
    }

}

 

posted @ 2023-05-11 18:23  DreamCatt  阅读(38)  评论(0)    收藏  举报