자바 는 Deferred Result 를 이용 하여 http 폴 링 실시 간 으로 데이터 인 터 페 이 스 를 되 돌려 줍 니 다.
8769 단어 JavaDeferredResulthttp 폴 링인터페이스
1.메시지 가 도착 하지 않 을 때 이 http 메시지 연결 은 다 져 지고 되 돌아 오지 않 습 니 다.http 는 짧 은 연결 이기 때문에 이 http 메시지 연결 은 최대 90 초 까지 다 져 지면 끊 깁 니 다(이것 은 브 라 우 저 나 웹 서버 의 행동 입 니 다).
2.1 의 경우 http 메시지 연결 이 끊 기 면 http 메시지 연결 을 다시 시작 합 니 다.
이 때 1 과 2 의 협조 하에 브 라 우 저 와 웹 서버 사이 에 영원히 메시지 가 연 결 됩 니 다.그리고 또 하나의 상황 이 있 습 니 다.
3.메 시 지 를 받 을 때마다 이 메시지 연결 은 즉시 메 시 지 를 브 라 우 저 페이지 로 가 져 오고 돌아 오 면 http 메시지 연결 을 다시 시작 합 니 다.
이렇게 하면 http 엔 드 로 폴 링 을 연결 하 는 방식 으로 실시 간 으로 메 시 지 를 받 을 수 있 습 니 다.그러나 설명 이 필요 한 것 은 사실 또 하나의 상황 이 있 습 니 다.메시지 가 도 착 했 을 때 이전 http 메시지 연결 이 되 돌아 오고 있 습 니 다.즉,두 번 째 상황 에서 갑자기 메시지 가 왔 습 니 다.이때 http 메시지 연결 을 사용 할 수 없습니다.이론 적 으로 http 메시지 연결 의 귀환 은 순간 적 이 고 메시지 연결 이 나타 날 확률 이 매우 낮 지만 머 피 법칙 에 따 르 면 이런 상황 이 반드시 나타 날 것 이라는 것 을 알 고 있 습 니 다.그래서 이런 상황 에서 우 리 는 소식 을 잠시 메시지 풀 에 저장 할 수 있 습 니 다.다음 소식 연결 이 도착 한 후에 기다 릴 필요 가 없습니다.직접 메시지 풀 에 가서 소식 을 찾 고 소식 을 가 져 올 수 있 습 니 다.그리고 즉시 새로운 메시지 연결 을 만 드 는 것 으로 돌아 가면 됩 니 다.
그러나 이상 은 오늘 이 글 의 중점 이 아니 라 오늘 이 글 의 제목 과 아무런 관계 가 없다.중요 한 것 은 심 검 선생님 의 이 글 을 본 후에 저 는 첫 번 째 단계 에서 어떻게 다 지 느 냐 는 의문 이 있 었 습 니 다.sleep 할 수 없 잖 아 요.얼마나 우아 하지 않 아 요.비슷 한 수 요 를 겪 어 본 적 이 없다 고 생각 했 기 때문에 몇 년 동안 저도 이 문 제 를 깊이 연구 하지 못 했 습 니 다.하지만 마음 속 으로 는 기억 하고 있 습 니 다.얼마 전에 마 병사 교육 의 공개 수업 을 들 었 습 니 다.그때 비슷 한 문 제 를 다시 이야기 할 때 http 의 연결 을 다 지 는 것 을 언급 했 습 니 다.(구체 적 으로 어떤 문제 인지 기억 이 나 지 않 습 니 다)당시 수업 시간 에 선생님 께 서 어떻게 실현 되 는 지 말씀 하지 않 으 셨 지만 평론 가 는 어떻게 다 져 서 돌아 오지 않 는 지 물 어 봤 습 니 다.그 다음 에 한 친구 가 Deferred Result 로 수업 이 끝 난 후에 자 료 를 찾 아 봤 는데 과연 가능 하 다 고 답 했다.다음 과 같이 실 현 된 노트 이기 때문에 이것 이 중점 이 고 이런 의문 이 있 는 친구 들 에 게 도 도움 이 되 었 으 면 좋 겠 다 고 말 했다.
1.메 시 지 는 실체 클래스 로 되 돌아 갑 니 다.여러분 은 실제 상황 에 따라 스스로 정의 하면 됩 니 다.
package cn.bridgeli.deferredresulttest.entity;
import lombok.Data;
import lombok.Getter;
/**
* @author bridgeli
*/
@Data
public class DeferredResultResponse {
private Integer code;
private String msg;
public enum Msg {
TIMEOUT(" "),
FAILED(" "),
SUCCESS(" ");
@Getter
private String desc;
Msg(String desc) {
this.desc = desc;
}
}
}
2.controller 인터페이스:
package cn.bridgeli.deferredresulttest.controller;
import cn.bridgeli.deferredresulttest.entity.DeferredResultResponse;
import cn.bridgeli.deferredresulttest.service.DeferredResultService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import javax.annotation.Resource;
/**
* @author bridgeli
*/
@RestController
@RequestMapping(value = "/deferred-result")
public class DeferredResultController {
@Resource
private DeferredResultService deferredResultService;
/**
* ,
* requestId
*/
private final String requestId = "test";
@GetMapping(value = "/get")
public DeferredResult<DeferredResultResponse> get(@RequestParam(value = "timeout", required = false, defaultValue = "10000") Long timeout) {
DeferredResult<DeferredResultResponse> deferredResult = new DeferredResult<>(timeout);
deferredResultService.process(requestId, deferredResult);
return deferredResult;
}
/**
* DeferredResult result ,
*
* @param desired
* @return
*/
@GetMapping(value = "/result")
public String settingResult(@RequestParam(value = "desired", required = false, defaultValue = " ") String desired) {
DeferredResultResponse deferredResultResponse = new DeferredResultResponse();
if (DeferredResultResponse.Msg.SUCCESS.getDesc().equals(desired)) {
deferredResultResponse.setCode(HttpStatus.OK.value());
deferredResultResponse.setMsg(desired);
} else {
deferredResultResponse.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
deferredResultResponse.setMsg(DeferredResultResponse.Msg.FAILED.getDesc());
}
deferredResultService.settingResult(requestId, deferredResultResponse);
return "Done";
}
}
그 중에서/get 인 터 페 이 스 는 심 검 선생님 이 말씀 하신 메시지 연결 을 모 의 한 것 입 니 다./result 인 터 페 이 스 는 새로운 소식 이 온 것 을 모 의 한 다음/get 인 터 페 이 스 는 바로 돌아 갑 니 다.주요 한 것 은 requestId 입 니 다.실제 프로젝트 에서 같은 것 을 사용 할 수 없습니다.그렇지 않 으 면 문제 가 발생 할 수 있 습 니 다.이 테스트 를 통 해 알 수 있 고 원인 도 쉽게 생각 할 수 있 습 니 다.3.서비스 실현:
package cn.bridgeli.deferredresulttest.service;
import cn.bridgeli.deferredresulttest.entity.DeferredResultResponse;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
/**
* @author bridgeli
*/
@Service
public class DeferredResultService {
private Map<String, Consumer<DeferredResultResponse>> taskMap;
public DeferredResultService() {
taskMap = new ConcurrentHashMap<>();
}
/**
* id setResult
*
* @param requestId
* @param deferredResult
*/
public void process(String requestId, DeferredResult<DeferredResultResponse> deferredResult) {
//
deferredResult.onTimeout(() -> {
taskMap.remove(requestId);
DeferredResultResponse deferredResultResponse = new DeferredResultResponse();
deferredResultResponse.setCode(HttpStatus.REQUEST_TIMEOUT.value());
deferredResultResponse.setMsg(DeferredResultResponse.Msg.TIMEOUT.getDesc());
deferredResult.setResult(deferredResultResponse);
});
Optional.ofNullable(taskMap)
.filter(t -> !t.containsKey(requestId))
.orElseThrow(() -> new IllegalArgumentException(String.format("requestId=%s is existing", requestId)));
taskMap.putIfAbsent(requestId, deferredResult::setResult);
}
/**
*
* DeferredResult setResult
*
* @param requestId
* @param deferredResultResponse
*/
public void settingResult(String requestId, DeferredResultResponse deferredResultResponse) {
if (taskMap.containsKey(requestId)) {
Consumer<DeferredResultResponse> deferredResultResponseConsumer = taskMap.get(requestId);
// DeferredResult setResult
deferredResultResponseConsumer.accept(deferredResultResponse);
taskMap.remove(requestId);
}
}
}
글 마지막 으로 저 는 다른 문 제 를 설명 하고 싶 습 니 다.우 리 는 Deferred Result 를 이용 하여 http 폴 링 을 실 현 했 습 니 다.사실은 생각 을 바 꾸 어 문 제 를 생각 합 니 다.우 리 는 http 인터페이스 지연 을 실현 하지 않 았 습 니까?따라서 시간 을 끌 고 돌아 갈 필요 가 있다 면 Deferred Result 를 통 해 이 루어 질 수 있 습 니 다.이상 은 자바 가 Deferred Result 를 이용 하여 http 폴 링 을 실현 하여 실시 간 으로 데이터 인터페이스 로 돌아 가 는 상세 한 내용 입 니 다.자바 가 http 폴 링 을 실현 하여 실시 간 으로 데이터 인터페이스 로 돌아 가 는 자 료 는 우리 의 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.