2012-12-02 60 views
58

在服務器端使用Sinatra和stream塊。通過Nginx發送EventSource/Server事件

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; 
    } 
} 

試圖keepalive 1024upstream部分以及proxy_set_header Connection keep-alive;location

沒有什麼幫助:(

沒有持續的連接和郵件不會傳遞到任何客戶端。

回答

122

你Nginx的配置是正確的,你只是錯過幾行。

這裏是一個「魔術三人組」使EventSource通過Nginx的工作:

proxy_set_header Connection ''; 
proxy_http_version 1.1; 
chunked_transfer_encoding off; 

它們放入location部分,它應該w ^掃。

你也可能需要添加

proxy_buffering off; 
proxy_cache off; 

這不是做這件事的一個正式的方式。

我結束了這種通過「試錯」 +「谷歌搜索」 :)

+0

哦,就是這樣!現在工作!向公衆發起我的超級聊天!萬分感謝! –

+0

它適用於我與ngix的nodejs服務器,我也使用EventSource.thanks。 –

+1

工作得很好。男人,這很難調試。非常感謝! –

3

不要從頭開始自己寫這個。 Nginx是一個非常棒的服務器,它擁有可以處理SSE的模塊,而不會降低上游服務器的性能。

退房https://github.com/wandenberg/nginx-push-stream-module

它的工作方式是用戶(使用SSE瀏覽器)連接到Nginx等連接停在那裏。發佈者(您的服務器在Nginx後面)將在相應的路由上向Nginx發送POST,並且在那一刻Nginx將立即轉發到瀏覽器中正在等待的EventSource偵聽器。

此方法比您的ruby webserver處理這些「長輪詢」SSE連接更具可擴展性。