93

streamブロックでSinatraを使用するサーバー側。

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と、接続が切断され、約1秒ごとに再接続が発生します。

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 1024ました。upstreamproxy_set_header Connection keep-alive;location

何も役に立ちません:(

永続的な接続はなく、メッセージはどのクライアントにも渡されません。

4

3 に答える 3

224

あなたの Nginx 設定は正しいです。いくつかの行が欠けているだけです。

EventSourceこれは、 Nginxを介して機能する「魔法のトリオ」です。

proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;

それらをlocationセクションに配置すると、機能するはずです。

追加する必要がある場合もあります

proxy_buffering off;
proxy_cache off;

それはそれを行う公式の方法ではありません。

私は「試行錯誤」+「グーグル」によってこれに行き着きました:)

于 2012-12-02T20:05:13.663 に答える
11

これを最初から自分で書かないでください。Nginx は素晴らしいイベント サーバーであり、アップストリーム サーバーのパフォーマンスを低下させることなく SSE を処理するモジュールを備えています。

https://github.com/wandenberg/nginx-push-stream-moduleをご覧ください

それが機能する方法は、サブスクライバー (SSE を使用するブラウザー) が Nginx に接続し、そこで接続が停止することです。パブリッシャー (Nginx の背後にあるサーバー) は、対応するルートで POST を Nginx に送信し、その瞬間、Nginx はブラウザーで待機している EventSource リスナーにすぐに転送します。

この方法は、Ruby Web サーバーにこれらの「ロングポーリング」SSE 接続を処理させるよりもはるかにスケーラブルです。

于 2015-02-14T20:42:55.463 に答える