EventSource /服务器通过Nginx发送事件

hmmo2u0o  于 2023-05-06  发布在  Nginx
关注(0)|答案(4)|浏览(616)

在服务器端使用Sinatra和stream块。

get '/stream', :provides => 'text/event-stream' do
  stream :keep_open do |out|
    connections << out
    out.callback { connections.delete(out) }
  end
end

在客户端:

var es = new EventSource('/stream');
es.onmessage = function(e) { $('#chat').append(e.data + "\n") };

当我通过http://localhost:9292/直接使用应用程序时,一切都很完美。连接是持久的,所有消息都传递到所有客户端。
然而,当它通过Nginx,http://chat.dev时,连接被丢弃,并且每隔一秒左右就会触发一次重新连接。
Nginx安装看起来不错:

upstream chat_dev_upstream {
  server 127.0.0.1:9292;
}

server {
  listen       80;
  server_name  chat.dev;

  location / {
    proxy_pass http://chat_dev_upstream;
    proxy_buffering off;
    proxy_cache off;
    proxy_set_header Host $host;
  }
}

upstream部分尝试了keepalive 1024,在location部分尝试了proxy_set_header Connection keep-alive;
没有什么帮助:(
没有持久连接,消息未传递到任何客户端。

kq0g1dla

kq0g1dla1#

你的Nginx配置是正确的,你只是错过了几行。
下面是一个通过Nginx制作EventSource的“魔术三重奏”:

proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;

将它们放入location部分,它应该工作。
您可能还需要添加

proxy_buffering off;
proxy_cache off;

这不是正式的做法
我最终通过“试错”+“谷歌搜索”得到了这个:)

k75qkfdt

k75qkfdt2#

另一种选择是在响应中包含一个值为“no”的“X-Accel-Buffering”头。Nginx特别对待它,请参阅http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering

kcugc4gi

kcugc4gi3#

不要自己从头开始写这篇文章。Nginx是一个很棒的事件服务器,它的模块可以为您处理SSE,而不会降低上游服务器的性能。
查看https://github.com/wandenberg/nginx-push-stream-module
它的工作方式是订阅者(使用SSE的浏览器)连接到Nginx,连接停止在那里。发布者(Nginx背后的服务器)将在相应的路由上向Nginx发送POST,此时Nginx将立即转发到浏览器中等待的EventSource侦听器。
这种方法比让你的ruby web服务器处理这些“长轮询”SSE连接更具可扩展性。

b09cbbtk

b09cbbtk4#

您好,将此评论从Did提升到答案:这是我通过Nginx使用HttpStreamingResponse从Django流式传输时唯一需要添加的东西。上面的所有其他开关都没有帮助,但这个标题有帮助。
让服务器响应“X-Accel-Buffering:no”header帮助很大!(见:wiki.nginx.org/X-accel#X-Accel-Buffering)-2013年7月1日16:24

相关问题