Server SSE服务器发送事件-客户端持续发送请求(如池)

Server SSE服务器发送事件-客户端持续发送请求(如池),server,comet,server-sent-events,Server,Comet,Server Sent Events,为什么每个站点都解释说,在SSE中,客户端和服务器之间的单个连接保持打开状态“使用SSE,客户端发送标准HTTP请求请求事件流,服务器最初使用标准HTTP响应进行响应,并保持连接打开” 然后,当服务器决定它可以向客户端发送数据,而我试图实现SSE时,每隔几秒钟就会看到fiddler请求被发送 对我来说,这感觉就像长时间的投票,没有一个连接保持打开 此外,并不是服务器决定向客户机发送数据,而是仅在客户机发送下一个请求时才发送数据 如果我回答“重试:10000”,即使发生了服务器想要立即通知的棘手问

为什么每个站点都解释说,在SSE中,客户端和服务器之间的单个连接保持打开状态“使用SSE,客户端发送标准HTTP请求请求事件流,服务器最初使用标准HTTP响应进行响应,并保持连接打开”

然后,当服务器决定它可以向客户端发送数据,而我试图实现SSE时,每隔几秒钟就会看到fiddler请求被发送

对我来说,这感觉就像长时间的投票,没有一个连接保持打开

此外,并不是服务器决定向客户机发送数据,而是仅在客户机发送下一个请求时才发送数据

如果我回答“重试:10000”,即使发生了服务器想要立即通知的棘手问题,也只会在下一个请求(从现在起10秒钟内)时到达客户端,而对我来说,这看起来不像是保持打开的连接,服务器会尽快发送数据

您的服务器正在立即关闭连接。SSE有一个内置的重试功能,用于连接丢失时进行重试,因此您看到的是:

  • 客户端连接到服务器
  • 服务器自动死亡
  • 客户端等待两秒钟,然后自动重新连接
  • 服务器自动死亡
  • 客户端等待两秒钟,然后自动重新连接
要修复服务器端脚本,您需要违背您的父母教给您的关于是非的一切,故意创建一个无限循环。因此,它最终会看起来像这样:

validate user, set up database connection, etc.
while(true){
  get next bit of data
  send it to client
  flush
  sleep 2 seconds
  }
validate user, set-up, etc.
while(true){
  calculate next 1000 digits of pi
  send them to client
  flush
  }
其中,
get next bit of data
可能会轮询DB表以查找自上次轮询以来的新记录,或者扫描文件系统目录以查找新文件,等等

或者,如果服务器端进程是长时间运行的数据分析,则您的脚本可能如下所示:

validate user, set up database connection, etc.
while(true){
  get next bit of data
  send it to client
  flush
  sleep 2 seconds
  }
validate user, set-up, etc.
while(true){
  calculate next 1000 digits of pi
  send them to client
  flush
  }

这假设计算行运行至少需要半秒;再频繁一点,你就会开始用大量的小数据包堵塞套接字,而没有任何好处(用户不会注意到他们每秒更新10次,而不是每秒更新2次)。

非常感谢你的回答。我开始理解事情,并得出了相同的结论,但后来我又提出了另一个问题。请注意:我想说的是,在服务器中使用这个无限循环,并为每个客户端保留一个线程,看起来就像一个服务器,在几个客户端之后,它将无法响应任何请求。我不知道信号器的内部结构,但我试图回答您的另一个问题。您有2个以上的线程(除非您将web服务器配置为只允许2个同时连接)。一般来说,问题在于保持每个套接字打开所需的大量内存,而不是线程/进程的可用性,并且每个服务器的并发客户端数将达到大约200到2000个。这是一个折衷办法:SSE可以降低延迟,但代价是必须保持更多的资源处于打开状态。是的,我确实有两个以上的线程,但问题是,当用户查看需要从服务器更新的特定页面时,线程会永远运行(while(true)loop)。这意味着,除了用于处理新服务器请求的其他线程外,200个用户=200个繁忙线程将永远运行