在ASP.NET MVC 5中,可以使用Web API的方式来实现SSE。当客户端与服务器进行长连接时,在客户端进行多个http请求时,会出现某些http请求被阻塞的情况。这是由于在进行长连接时,只有一个线程被启用,而长连接并不会释放线程。因此,当客户端进行多个http请求时,只有第一个http请求能够正常响应,而其他的http请求则被阻塞。
解决这个问题的方法是,在建立长连接时,使用异步控制,使用Task.Run()方法将长连接的处理程序放在一个新线程中运行,避免阻塞主线程。
以下是示例代码:
public class SSEController : ApiController
{
// GET api/ssetest
public HttpResponseMessage Get()
{
HttpResponseMessage response = Request.CreateResponse();
response.Content = new PushStreamContent(async (stream, content, context) =>
{
// Start SSE
while (true)
{
// Do long running task here
await Task.Delay(1000);
// Notify client
var sseEvent = new SseEvent(DateTime.Now.ToString(), "hello, world!");
var sseData = JsonConvert.SerializeObject(sseEvent);
var sseBytes = Encoding.UTF8.GetBytes($"event: sseEvent\ndata: {sseData}\n\n");
await stream.WriteAsync(sseBytes, 0, sseBytes.Length);
await stream.FlushAsync();
}
});
response.Headers.Add("Content-Type", "text/event-stream");
return response;
}
}
在上述代码中,我们首先创建了一个返回HttpResponseMessage对象的Web API接口方法。该方法返回一个长连接的响应流,同时使用异步控制,将长连接处理程序放在一个新线程中运行。
在长连接处理程序中,我们实现了每隔1秒向客户端发送一条SSE消息的功能。在向客户端发送SSE消息时,我们使用了UTF8编码,并将消息格式化为SSE格式。最后,我们通过FlushAsync()方法将消息发送给客户端,并释放资源,使得其他http请求能正常响应。
通过使用异步控制,我们避免了长连接阻塞主线程