2016-12-07 20 views
5

私はAjax Comet long-pollingを使用するC#ASP.Net(非MVC)プロジェクトを持っています。 Webページは、IHttpAsyncHandlerを実装するクラスによって処理されるエンドポイントへのHTTP呼び出しを行います。WebAPI2経由でC#Ajax Cometを実行するには?

Webページに何も報告しない場合(n秒以内に)、空のHTTP応答が送信され、Webページが再度呼び出します。送信するものがあれば、更新が送信され、ウェブページの処理と再呼び出しが行われます。これはかなり標準的なプッシュ技術であり、とてもうまく動作します。

今、WebAPI2、非MVCを使用してAPIエンドポイントを追加しようとしています。私はApiControllerクラスに基づいて動作する同期コントローラを持っています。

私はAPI呼び出しのプッシュ技術を設定して、APIユーザーが更新をポーリングする必要がないようにしたいと考えています。

上記の方法と同様に、APIエンドポイントコールが受信され、コンテキストが保存されます。タイムアウトが満了すると、呼び出しは空に戻され、呼び出し元は再び呼び出されることが予想されます。タイムアウト時間内にデータが更新されると、データは呼び出し元に返され、呼び出し元は再度呼び出され、更なる更新を待つことになります。

問題は、非同期バージョンのApiControllerがないようです。 APIコールを処理しているスレッドを解放してプールに戻し、使用可能なデータがある場合やタイムアウトが経過すると、応答を返すためにワーカースレッドが使用されます。

コールを処理するスレッドが解放され、コールコンテキストが保存され、後でコールに応答を送信できるようにするには、どのようにしてApiControllerを設定できますか?

+1

なぜSignalRを使用しないのですか? –

+0

ロングポーリングは非常に効率的で、特に品質の低い接続の場合に効率的です。それはうまくいきます。 WebAPI2接続を標準のHTTP要求と同じようにハングアップする方法を理解する必要があります。 –

答えて

2

あなたはすなわち欲しいものを達成するために/非同期を待つ使用することができます。この例のWeb APIメソッドがasyncとして宣言され、そのボディにawaitオペレータがプールにスレッドを返すために使用されたで

[HttpPost] 
public async Task<HttpResponseMessage> LongRunningOperation([FromBody]Input obj) 
{ 
    // Do what ever you need with input data   

    await WaitForEvent();   

    // Do what ever you need to return a response 

    return someResponse; 
} 

私は、Cometを実装するために、何らかのイベントを使用すると仮定しました。私が長年前に覚えている限り、私はManualResetEventを使っていました。しかし、それは他のものにすることができます。

重要なことは、WaitForEventメソッドが待っているものを返す必要があることです。つまり、ManualResetEventまたは他の待機ハンドルをタスクにラップする必要があります。あなたはAsyncFactory.FromWaitHandleメソッドでそれを行うことができます。

これは、Web APIのコンテキストで、asyn/awaitについて読むことも価値があります。discussion

+0

私はイベントを他の場所で使用していますが、通常のスレッドの論争のために使用しましたが、ここでは使用することは考えていませんでした。私はこれを試してみる。 –

+0

ウェブサイトの彗星については、現在私は非同期のHTTPハンドラを使用しています。これは、httpコンテキストをラップする派生AsyncResultオブジェクトを作成します。 AsyncResultオブジェクトは、タイムアウトが経過するかデータが到着するまでコレクションに格納されます。いずれかが発生すると、コンテキスト要求が完了します。クライアントは、タイムアウト時に空の応答を返すか、タイムアウト(つまり古典的な彗星)の前にしばらくしてデータを返すか、どちらかの方法でクライアントループと再要求を行います。クライアントは、ほとんどの場合、スレッドを縛ることなく、データを受動的に接続して接続します。 –

関連する問題