事件源/服务器 – 通过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连接更具可扩展性。