Does SignalR Server Sent Events implementation occupy thread for each connection?

对着背影说爱祢 提交于 2019-12-11 05:05:17

问题


When I use signalR which falls back to ServerSentEvents, and I can see on fiddler an open connection to the server waiting for chunked data, does it mean a thread is being occupied on the server at this time?

If so, it is not quite efficient as far as I see it..

For example I would not write such code in the server that blocks a thread:

public ActionResult ServerSentEvents
{
    DateTime currentdate = DateTime.Now;
    Response.ContentType = "text/event-stream";
    while (currentdate.AddMinutes(1) > DateTime.Now)
    {
        Response.Write(string.Format("data: {0}\n\n", DateTime.Now.ToString()));
        Response.Flush();
        System.Threading.Thread.Sleep(1000);
    }
}

Could it be that SignalR does something more efficiently here?


回答1:


That looks like MVC Controller code not SignalR Hub code

Anyway, SignalR supports the async framework in .NET 4.5 so you could return a Task from that method instead and have one background thread handling the wait state and when a task has waited 1000 MS you will continue that task.

You should never ever have Thread.Sleep in a requst thread, it kills scalability completely, and its the reason why Frameworks like Entity Framework and ADO.NET supports async operations (A I/O operation like Database is just like a Thread.Sleep)

edit: If you for no reason want to use SignalR you can use Tasks from MVC 4 or the AsyncController in MVC 3 and earlier. But I would recommend SignalR since they are doing all the plumbing for you




回答2:


Yes. (or "Maybe", depending on how SignalR is implemented.)

SSE keeps a socket open between the server and client. You said you wouldn't write code that does System.Threading.Thread.Sleep(1000); but it seems efficient enough. When you put a thread to sleep, it stops using a CPU core, and another thread will get its chance to run on the CPU.

It is possible SignalR does not use one thread per client connection. It may use a while loop that loops through socket handles, and tries a read on each one in turn, but running in a single thread. (e.g. PHP does not support threads, so if you want to run a multi-client server that is how you do it). Efficiency-wise that is in the same ballpark as using threads. But threads are a low-cost abstraction which generally make the coding a little easier.

It sounds to me like you are doing premature optimization. Unless profiling has shown your bottleneck is the overhead of the context switch as threads are moved on and off the CPU, this is not something to worry about.




回答3:


Your example is very strange. If it was meant like example of totally wrong server code, then its perfect.. ..anyway who handles actual connection (and reading from it) depends on how you host your server (IIS vs self host using Owin).

  • IIS - im pretty sure there is no thread blocking for each connection. IIS handles reading from socket using something like IO completion ports

  • Owin\HttpListener - here i'm equally sure SignalR is using async operations for reading from connection (and waiting for data). Which under covers also use IO completion ports.

-> No thread is blocked on server while connection is opened and not receiving data from client...



来源:https://stackoverflow.com/questions/30421318/does-signalr-server-sent-events-implementation-occupy-thread-for-each-connection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!