How to make C # Ajax Comet via WebAPI2?

I have a C # ASP.Net project (not MVC) that uses a long Ajax Comet poll. The web page makes an HTTP call to the endpoint handled by the class that implements IHttpAsyncHandler.

If there is nothing to report (within n seconds) to the web page, an empty HTTP response is sent and the web page rings again. If there is something to send, and the update is sent, and the web page processes and calls back. This is pretty standard push technology and works very well.

Now I'm trying to add API endpoints using WebAPI2, not MVC. I have synchronous controllers based on the ApiController class.

I would like to configure push technology for API calls so that API users do not have to request updates.

Like the method described above, an API endpoint call is received and the context is saved. If the timeout expires, the call returns empty and the caller must call again. If the data is updated during the timeout, the data is returned to the caller, and after that it is expected that the caller will call again and wait for more updates.

The problem is that there seems to be no asynchronous version of ApiController. The goal is to free the thread that processes the API call, return it to the pool, and then when there is data or timeout, the workflow is used to return the response.

How to configure ApiController so that the thread processing the call is released, the call context is saved, and I can send the answer to the call at a later point in time?

+5
source share
1 answer

You can use async / wait to achieve what you want ie:

[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; } 

In this example, the Web API method is declared as async , and in its await body, the operator was used to return the stream to the pool.

I suggested that you use some events to implement the comet. As far as I remember many years ago, I used ManualResetEvent for this. However, it could be anything.

The important thing is that the WaitForEvent method should return something expected. In other words, ManualResetEvent or another wait descriptor must be wrapped in a task. You can do this using the AsyncFactory.FromWaitHandle method.

It's also worth reading this discussion about asyn / await in the context of the Web API.

+2
source

Source: https://habr.com/ru/post/1260923/


All Articles