我出出主意,如何可以實現。這是問題,以及我已經嘗試過的。與ASPNET核心雙向通信和WebSockets的
問題
有一個消息隊列與來自外部系統來的消息。客戶端必須打開與服務器的websocket連接,並在插入時立即從隊列接收這些消息。除此之外,客戶端可以在同一WebSocket連接(在客戶端和服務器之間的通信必須具有儘可能低的等待時間儘可能)發送命令到服務器。
工具
我更喜歡使用的最低水平,但仍然實用,官方庫,這樣的選擇是Microsoft.AspNetCore.WebSockets(1.0.0)。該應用程序作爲啓用了Websockets(WSS)的Web應用程序在Azure App Service上運行。該應用程序是netcoreapp1.1。沒有要求SSE /長輪詢/等後備(SignalR)。
解決方案#1 - 已經測試
服務器應該運行一個循環:
- 發送任何更新,如果消息隊列不爲空。
- 等待與超時的傳入消息。
這可能是這樣實施:
while (_request_not_aborted_) // The condition is simplified.
{
if (_there_is_a_new_message_in_message_queue_)
{
// Send all available messages from the message queue.
await SendAsync();
}
using (var timeoutCancellationTokenSource = new CancellationTokenSource())
{
var timeoutCancellationToken = timeoutCancellationTokenSource.Token;
var receiveTask = ReceiveAsync(timeoutCancellationToken, webSocket);
// Wait for any incoming message for 1000ms and cancel the task if
// the client hasn't sent any yet.
if (await Task.WhenAny(receiveTask, Task.Delay(1000, timeoutCancellationToken)) ==
receiveTask)
{
var result = await receiveTask;
// Process the message.
}
timeoutCancellationTokenSource.Cancel();
}
}
解決方案#1 - 什麼是錯的?
一旦取消timeoutCancellationTokenSource,websocket連接進入「中止」狀態,客戶端斷開連接。
可能相關的問題:https://github.com/aspnet/WebSockets/issues/68
解決方案#2 - 已經測試
使用SSE從服務器流式傳輸數據到客戶端,並使用常規的HTTPS請求,將消息發送回。
解決方案#2 - 有什麼不對?
的HTTPS請求的等待時間是不可接受的,並且未在IE /邊緣尚不支持SSE。
溶液#3
使用多個WebSocket連接,一個用於服務器 - >客戶端,另一個用於客戶端 - >服務器的通信。
解決方案#3 - 有什麼不對?
但是,這會增加斷開連接錯誤的機會,並且一般來說聲音不好,因爲websocket技術應該提供雙向通信。
溶液#4
使用溶液#2的超時邏輯移除,但是從客戶機到服務器的每1000毫秒,以允許ReceiveAsync正常完成發送NOOP消息。
解決方案#4 - 有什麼問題?
聽起來像一個討厭的解決方法。
請求幫助/想法
也許知道任何其他解決方案的服務器可以如何監聽傳入的消息,並在相對同時將消息發送到客戶端?
附加發現
- 「恰好一個發送和一個接收被支撐在平行各WebSocket的對象上。」 MSDN
你在使用什麼消息隊列? – jao
Azure雲存儲 – Zygimantas