Nginx/NChan の設定

Nginx/NChan の設定

私が開発しているモバイル アプリでは、WebSocket を使用してさまざまな情報をサブスクライブ/公開しています。ほとんどの場合、アプリ側の WebSocket は単なるリスナーです。ただし、メッセージを公開する場合もあります。

サーバー側では、Nginx 上で動作する [NChan][1] の組み合わせを使用してこれを処理しています。NChan の非常に優れた機能の 1 つは、Web ソケットを「多重化」する機能です。つまり、複数のチャネルで pub/sub を実行できます。モバイル アプリを作成する場合、この機能は整理整頓とバッテリーの耐久性を大幅に向上させます。

[NChanドキュメント][2]で説明されているように、多重化されたpubsubチャネルを設定しました

location ~ /pubsub/(\w+)/(\w+)/(\w+)/(\w+)/(\w+)$ 
{
 nchan_pubsub;
 nchan_channel_id "$1" "$2" "$3" "$4" "$5" "control";
 nchan_publisher_upstream_request /alter;
}

上記の3行目は、受信したリクエストを別のサーバーにchan_publisher_upstream...転送します。pub

location = /alter 
{
 proxy_pass https://example.com;
 proxy_set_header X-Publisher-Type $nchan_publisher_type;
 proxy_set_header X-Prev-Message-Id $nchan_prev_message_id;
 proxy_set_header X-Channel-Id $nchan_channel_id;
 proxy_set_header X-Original-URI $request_uri;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header Upgrade $http_upgrade;
 proxy_set_header Connection "upgrade";
} 

index.php他のサーバーでは、サーバーのルートフォルダー内でPHPを実行するためにNginxを設定しました。

<?php
 trigger_error(json_encode(getallheaders()));//a test to see that the proxy pass is actually 
 happening
 
 header("HTTP/1.1 304 Not Modified");
 //if successful should cause the incoming request to be published without changes
 
 //header("HTTP/1.1 204 No Content");
 //when enable will suppress the incoming request (optionally after doing some server-side
 //stuff with the incoming request data

 //header("HTTP/1.1 200 OK"); 
 //echo 'New Content!';
 //when enabled should replace the incoming requestt content with the new one 
 ?>

私が知る限り、私はNChanの指示にかなり忠実に従っています。しかし、この設定を使用して、今定義したpubsubチャネルに公開しようとすると、クライアント接続が予期せず閉じられてしまいます。このテストを実行するために、私はいくつかの簡単なJavaScriptを使用しています。

    var socket;

    function connectPubSub()
    {
     socket = new WebSocket("wss://app.server.url/pubsub/personal/cause/beacon/grid/chat");
     socket.onopen = whenOpen;
     socket.onmessage = whenMessage;
     socket.onclose = whenClose;
     socket.onerror = whenError;
    } 

    function whenOpen(e){console.log("[open] Connection established");}

    function whenMessage(event){console.log(`[message]:${event.data}`);}

    function whenClose(event) 
    {
     if (event.wasClean) 
      alert(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
      else console.log('[close] Connection died');
    }

    function whenError(error){console.log(`[error] ${error.message}`);}

    function sendMessage(msg){socket.send(msg);}

この時点で、次のものを発行しようとすると

connectPubSub();
sendMessage('Hello world!');

以下のような出力が得られます

[open] Connection Established
Websocket connection to app.server.url failed:Close received after close

エラーイベントは以下のとおりです

bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: WebSocket {url: "wss://app.server.url/pubsub/personal/cause/beacon/grid/chat", 
readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
defaultPrevented: false
eventPhase: 0
isTrusted: true
path: []
returnValue: true
srcElement: WebSocket {url: "wss://app.server.url/pubsub/personal/cause/beacon/grid/chat", 
readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
target: WebSocket {url: "wss://app.server.url/pubsub/personal/cause/beacon/grid/chat", 
readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
timeStamp: 83208.4250000189

これは困惑させられます。NChanのドキュメントに従って、多重化されたチャネルにメッセージを公開し、pubsubプロキシサーバーでメッセージの内容(JSON)を調べてから、何をすべきかを決めるだけだと思っていました。

  • メッセージを通過させる(HTTP 304を発行する)
  • サーバー側でアクションを実行し、メッセージを抑制します(HTTP 204 を発行します)
  • メッセージを変更して送信します(HTTP 200を発行します)

Nginx 構成ディレクティブに関する私のかなり不十分な知識が、ここで私を失敗させているのかもしれません。何が間違っているのでしょうか?


ここで何が起こっているのか、今や私は突き止めることができた。ここでの問題の根源は、

proxy_pass https://example.com;

指令。これを変更すれば

proxy_pass https://example.com/index.php;

期待通りに動作します。しかし、なぜこのようなことが起こるのかは私にはまだ分かりません。私のNginxのデフォルト設定ファイルの先頭には、次の行があります。

server 
{
 root /path/to/root;
 index index.php;

 server_name example.com;

上記の 3 行目は、Nginx に任意のフォルダー/サブフォルダーの場所で index.php を実行するように指示するのに必要なほぼすべてだと思いましたindex index.php。明らかにそうではありませんか? [1]:https://nchan.io [2]:https://nchan.io/#getting-started

関連情報