2013-02-13 119 views
1

我有一個請求/響應協議運行在TCP上,我想提供一個異步/等待API。該協議是STOMP,它是一種基於TCP或SSL運行的相當簡單的基於文本的協議。在STOMP中,客戶端發送六個左右命令幀中的一個,並在該命令的頭部指定一個receipt ID。服務器將以RECEIPTERROR框架與receipt-id字段進行響應,因此客戶端可以將響應與原始請求進行匹配。服務器也可以隨時發送一個MESSAGE幀(STOMP基本上是一個消息協議),它不包含receipt-id創建包裝請求/響應協議的異步/等待API

要允許多個未完成的請求並處理任何MESSAGE幀,計劃始終有一個Socket.BeginReceive()未完成。所以我在想的是最簡單的實現是創建一個可等待的事件(如互斥體),將該事件存儲在一個表中,將設置爲receipt的命令請求發送到表中並阻止該事件。當socket.BeginReceive()觸發功能可以從消息中獲得receipt-id,在表中查找事件併發信號(並存儲某種狀態,如成功或錯誤)。這將喚醒調用函數,該函數可以查看結果並將調用應用程序的成功或失敗返回。

這聽起來基本正確嗎?我以前使用過異步/等待API,但從未寫過自己的API。如果沒關係,我應該使用什麼樣的等待事件?一個簡單的Monitor.Wait()會阻止,但不是我想要的方式,對嗎?如果我將整個東西包裝在Task.Run()中,那麼Monitor.Wait()的行爲會正常嗎?或者是否有我應該使用的新同步構造?我基本上實施HttpClient.GetAsync(),有沒有人知道如何在封面下工作?

+0

試着看一下WCF http://msdn.microsoft.com/en-us/library/ms731082.aspx非常有效! – legrandviking 2013-02-13 23:37:26

回答

2

HttpClient要簡單得多,因爲HTTP對每個請求只有一個響應。 HTTP中不存在主動提供的服務器消息。

要正確設置這樣的事件「流」,最好使用TPL DataflowRx。否則,您必須創建一個無界的接收緩衝區並重復異步的ReceiveMessage調用。所以我建議使用TPL Dataflow管道創建一個「消息」源塊,然後匹配一些請求(使用TaskCompletionSource通知發件人它已完成)並將其餘(MESSAGE幀)公開爲源塊。

內部,你的處理管道應該是這樣的:

  • 重複BeginReceive - >
  • TransformBlock的消息框架 - >
    • ActionBlock到響應消息匹配請求。
    • BufferBlock對於MESSAGE幀。
+0

TPL DataFlow大有作爲。非常適合這種問題。 – spender 2013-02-14 01:09:06