2016-12-07 37 views
5

我有一个使用Ajax Comet长轮询的C#ASP.Net(非MVC)项目。网页对实施IHttpAsyncHandler的类所处理的端点进行HTTP调用。如何通过WebAPI2来完成C#Ajax Comet?

如果有什么报告(n秒内)的网页,一个空的HTTP响应发送,网页重新调用。如果有东西要发送,更新发送,网页处理和重新调用。这是非常标准的推送技术,并且工作得很好。

现在我尝试添加API端点,使用WebAPI2,非MVC。我有基于ApiController类的同步控制器工作。

我想设置推送技术的API调用,让API的用户不必轮询更新。

与上述方法类似,接收API端点调用并存储上下文。如果超时过期,则该呼叫将返回空,并且呼叫方需要再次呼叫。如果数据在超时内更新,数据将返回给调用者,然后调用者需要再次调用并等待更多更新。

问题是似乎没有ApiController的异步版本。其目的是释放正在处理API调用的线程,将其返回到池,然后当有数据可用或超时过期时,将使用工作线程返回响应。

我怎样才能建立一个ApiController使线程处理呼叫被释放,呼叫上下文存储,我可以把在稍后的时间点到调用的响应?

+1

你为什么不使用SignalR? –

+0

长轮询工作效率很高,特别适用于质量差的连接。它运作良好。我只需要弄清楚如何挂起WebAPI2连接,就好像它是一个标准的HTTP请求。 –

回答

2

您可以使用异步/伺机达到你想要的东西,即:

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

在这个例子中的Web API方法声明为async,并在其身上await运营商使用一个线程返回到池。

我认为,为了实施彗星你使用某种事件。据我多年前记得我用ManualResetEvent这样做。但是,它可以是其他任何东西。

什么重要的是,WaitForEvent方法应该返回的东西awaitable。换句话说,ManualResetEvent或其他等待句柄应该包装在一个任务中。你可以用AsyncFactory.FromWaitHandle方法做到这一点。

另外,值得一读的Web API的背景下,这个discussion约ASYN /等待。

+0

我在其他地方使用事件,对于正常的线程争吵,但没想到在这里使用它们。我会试试这个,感谢这篇文章。 –

+0

对于网站彗星,目前我使用异步Http处理程序。它创建一个包装http上下文的派生AsyncResult对象。 AsyncResult对象存储在集合中,直到超时或数据到达。当发生任何一种情况时,上下文请求完成。客户端在超时时遇到空响应,或者在超时之前的某个时间响应数据(即经典慧星),以及任何方式,客户端循环和重新请求。客户端几乎总是处于连接状态,被动地等待数据,而无需占用线程。 –