[英]Multiple Private WebSocket Messages with Spring
我正在使用Spring @RequestMapping來使用和生成JSON的REST同步服務。 現在,我想添加異步響應,即客戶端發送ID列表,服務器將詳細信息發送回去,因為它將詳細信息發送給一個客戶端。
我搜索了一段時間,沒有找到我想要的東西。 我已經看到了Spring的兩種不同方法。 最常見的是消息代理方法,其中似乎每個人都通過訂閱隊列或主題來獲取每條消息。 因為這是私人數據,所以這是非常不可接受的。 我也有有限數量的數據點要返回。 另一種方法是Callable,AsyncResult或DeferredResult。 這似乎使數據保密,但是我想發送多個響應。
我已經看到了與我想要的東西類似的東西,但是在服務器上使用了Jersey SSE 。 我想堅持使用Spring。
這是我目前使用偽代碼的方式。
@RequestMapping(value = BASE_PATH + "/balances", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public GetAccountBalancesResponse getAccountBalances(@RequestBody GetAccountBalancesRequest request) {
GetAccountBalancesResponse ret = new GetAccountBalancesResponse();
ret.setBalances(synchronousService.getBalances(request.getIds());
return ret;
}
這就是我想要做的。 因為我不了解細節,所以這很粗糙。 一旦確定發送,我將致力於異步部分,但會提出任何建議。
@RequestMapping(value = BASE_PATH + "/balances", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ???<BalanceDetails> getAccountBalances(@RequestBody GetAccountBalancesRequest request) {
final ???<BalanceDetails> ret = new ???<>();
new Thread(new Runnable() {
public void run() {
List<Future<BalanceDetails>> futures = asynchronousService.getBalances(request.getIds());
while(!stillWaiting(futures)) {
// Probably use something like a Condition to block until there is some details.
ret.send(getFinishedDetails(futures));
}
ret.close();
}
}).start();
return ret;
}
謝謝,韋斯。
它不是這樣工作的:您使用的是普通的Spring操作,這些操作旨在在possilby阻塞的單個線程中進行處理,直到計算出完整的請求為止。 您不會在控制器內部創建線程-或至少不會以這種方式創建線程。
如果計算持續很長時間,並且您想為用戶提供視覺反饋,請執行以下步驟:
如果還不夠,計算仍然會永遠持續下去,並且用戶需要反饋,您將有兩種選擇
進行了大量的挖掘工作,但看起來Spring Web 4.2確實支持服務器端事件。 我正在使用使用Spring Web 4.1.7的Spring Boot 1.2.7。 切換到Spring Boot 1.3.0.RC1將添加SseEmitter。
這是我的偽代碼。
@RequestMapping(value = BASE_PATH + "/getAccountBalances", method = RequestMethod.GET)
public SseEmitter getAccountBalances(@QueryParam("accountId") Integer[] accountIds) {
final SseEmitter emitter = new SseEmitter();
new Thread(new Runnable() {
@Override
public void run() {
try {
for (int xx = 0; xx < ids.length; xx++) {
Thread.sleep(2000L + rand.nextInt(2000));
BalanceDetails balance = new BalanceDetails();
...
emitter.send(emitter.event().name("accountBalance").id(String.valueOf(accountIds[xx]))
.data(balance, MediaType.APPLICATION_JSON));
}
emitter.send(SseEmitter.event().name("complete").data("complete"));
emitter.complete();
} catch (Exception ee) {
ee.printStackTrace();
emitter.completeWithError(ee);
}
}
}).start();
return emitter;
}
仍然可以正常關閉通道並使用Jersey EventSource解析JSON對象,但是它比消息總線要好得多。
此外,生成新線程並使用睡眠僅適用於POC。 我也不需要,因為我們已經有一個異步過程來訪問緩慢的后端系統。
韋斯
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.