Spring 은 Deferred Result 를 사용 하여 긴 연결 을 실현 합 니 다.

3216 단어 자바Spring
@RestController
@RequestMapping("/notifications")
public class NotificationResource implements ReleaseMessageListener {
    private static final Logger logger = LoggerFactory.getLogger(NotificationResource.class);

    private final Multimap deferredResults =
            Multimaps.synchronizedSetMultimap(HashMultimap.create());
    //    
    private final ExecutorService largeNotificationBatchExecutorService;


    public NotificationResource() {
        largeNotificationBatchExecutorService = Executors.newFixedThreadPool(20, BambooThreadFactory.create
                ("NotificationResource", true));
    }

    /**
     *         
     * @return
     */
    @RequestMapping(method = RequestMethod.GET)
    public DeferredResult> pollNotification(@RequestParam(value = "instanceId") String instanceId) {
        DeferredResultWrapper deferredResultWrapper = new DeferredResultWrapper(instanceId);
        deferredResultWrapper.onTimeout(() -> logger.debug("notifications timeout"));
        deferredResultWrapper.onCompletion(() -> deferredResults.remove("server", deferredResultWrapper));
        this.deferredResults.put("server", deferredResultWrapper);

        return deferredResultWrapper.getResult();
    }


    /**
     *       
     */
    @Override
    public void handleMessage() {
        logger.info("gray map modified");
        for (DeferredResultWrapper wrapper : (List) new ArrayList(deferredResults.get("server"))) {
            largeNotificationBatchExecutorService.submit(() -> wrapper.setResult(true));
        }

    }
}

알림 인터페이스
/**
 *     
 */
public interface ReleaseMessageListener {
    void handleMessage();
}

deferred Result 포장 류
/**
 *       
 */
public class DeferredResultWrapper {
    private static final long TIMEOUT = 60 * 1000;//60 seconds
    //     304
    private static final ResponseEntity
            NOT_MODIFIED_RESPONSE = new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
    private String instanceId;
    private DeferredResult> result;

    /**
     *     
     */
    public DeferredResultWrapper(String instanceId) {
        this.instanceId = instanceId;
        result = new DeferredResult<>(TIMEOUT, NOT_MODIFIED_RESPONSE);
    }

    //   
    public void onTimeout(Runnable timeoutCallback) {
        result.onTimeout(timeoutCallback);
    }

    public void onCompletion(Runnable completionCallback) {
        result.onCompletion(completionCallback);
    }

    /**
     *       
     * @param notification
     */
    public void setResult(boolean notification) {
        result.setResult(new ResponseEntity<>(notification, HttpStatus.OK));
    }

    public DeferredResult> getResult() {
        return result;
    }
}

인 터 페 이 스 를 호출 할 때 로 컬 에 등록 합 니 다.
60s 시간 초과 에 도착 하면 호출 자 304 에 게 돌아 갑 니 다.
60s 내 에 호출 자 에 게 알 리 려 면 true 와 200 으로 돌아 갑 니 다.

좋은 웹페이지 즐겨찾기