1

非同期/待機APIを提供したいTCP上で実行される要求/応答プロトコルがあります。プロトコルはSTOMPです。これは、TCPまたはSSL上で実行される非常に単純なテキストベースのプロトコルです。STOMPでは、クライアントは6つほどのコマンドフレームの1つを送信receiptし、コマンドのヘッダーでIDを指定します。サーバーは、RECEIPTまたはERRORフレームのいずれかでreceipt-idフィールドを使用して応答するため、クライアントは応答を元の要求と照合できます。サーバーは、MESSAGEを含まないフレームをいつでも送信できます(STOMPは基本的にメッセージングプロトコルです)receipt-id

複数の未処理の要求を許可し、任意のMESSAGEフレームを処理するために、計画では常にSocket.BeginReceive()未処理があります。したがって、私が考えていた最も簡単な実装は、待機可能なイベント(ミューテックスなど)を作成し、そのイベントをテーブルに格納receiptし、インデックスに設定されたコマンドリクエストをテーブルに送信し、イベントをブロックすることです。起動するsocket.BeginReceive()と、関数はreceipt-idメッセージからを取得し、テーブルでイベントを検索し、それを通知します(そして、成功やエラーなどの状態を保存します)。これにより、呼び出し元の関数がウェイクアップし、結果を確認して、呼び出し元のアプリケーションに成功または失敗を返すことができます。

これは根本的に正しいように聞こえますか?私は以前にasync/await APIを使用したことがありますが、自分でAPIを作成したことはありません。よろしければ、どのような待機可能なイベントを使用すればよいですか?単純なMonitor.Wait()ブロックはブロックされますが、私が望む方法ではありません、正しいですか?全部を包むと、Task.Run()それは正しく動作しMonitor.Wait()ますか?または、代わりに使用する必要がある新しい同期構造はありますか?私は基本的に実装HttpClient.GetAsync()していますが、それが内部でどのように機能するか知っている人はいますか?

4

1 に答える 1

2

HttpClientHTTPにはリクエストごとに1つの応答しかないため、はるかに簡単です。HTTPには、一方的なサーバーメッセージのようなものはありません。

このようなイベントの「ストリーム」を適切に設定するには、TPLDataflowまたはRxを使用するのが最適です。それ以外の場合は、無制限の受信バッファーを作成し、非同期のReceiveMessage呼び出しを繰り返す必要があります。

したがって、TPLデータフローパイプラインを使用して「メッセージ」のソースブロックを作成し、一部をリクエストと照合して(TaskCompletionSource送信者に完了を通知するために使用)、残り(MESSAGEフレーム)をソースブロックとして公開することをお勧めします。

内部的には、処理パイプラインは次のようになります。

  • 繰り返しBeginReceive->
  • TransformBlockメッセージフレーミング用->
    • ActionBlock応答メッセージを要求に一致させるため。
    • BufferBlockMESSAGEフレーム用。
于 2013-02-13T23:40:26.270 に答える