事件源/服务器 – 通过Nginx发送事件
在服务器端使用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
以及proxy_set_header Connection keep-alive;
在location
。
没有帮助:(
没有持久连接和消息没有传递给任何客户端。
你的Nginxconfiguration是正确的,你只是想念几行。
这是一个“魔术三人组”,使得EventSource
通过Nginx进行工作:
proxy_set_header Connection ''; proxy_http_version 1.1; chunked_transfer_encoding off;
把它们放在location
部分,它应该工作。
您可能还需要添加
proxy_buffering off; proxy_cache off;
这不是一个官方的做法。
我结束了这个“试错”+“谷歌search”:)
另一个select是在你的响应中包含一个值为'no'的'X-Accel-Buffering'头。 Nginx专门对待它,请参阅http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering
不要从头开始写这个。 Nginx是一个非常好的服务器,它拥有能够处理SSE的模块,而不会影响上游服务器的性能。
看看https://github.com/wandenberg/nginx-push-stream-module
它的工作方式是用户(使用SSE的浏览器)连接到Nginx,连接停在那里。 发布者(你的服务器在Nginx后面)将在相应的路由上发送一个POST到Nginx,那时Nginx会立即转发到浏览器中等待的EventSource监听器。
这个方法比你的ruby webserver处理这些“长轮询”的SSE连接更具可扩展性。