
In einer mobilen App, die ich entwickle, verwende ich WebSockets, um eine Reihe verschiedener Informationen zu abonnieren/veröffentlichen. In den meisten Fällen ist der WebSocket auf der App-Seite einfach ein Listener. Es gibt jedoch auch Fälle, in denen er eine Nachricht veröffentlicht.
Serverseitig handhabe ich dies mit einer Kombination aus [NChan][1], die auf Nginx läuft. Eine der wirklich netten Funktionen von NChan ist die Möglichkeit, einen Websocket zu „multiplexen“ – d. h. ihn auf mehreren Kanälen zu publizieren/subzuverwenden. Beim Erstellen einer mobilen App trägt dies wesentlich zur Verbesserung der Übersichtlichkeit und der Akkufreundlichkeit bei.
pubsub
Wie in der [NChan-Dokumentation][2] erklärt, habe ich Multiplexkanäle eingerichtet
location ~ /pubsub/(\w+)/(\w+)/(\w+)/(\w+)/(\w+)$
{
nchan_pubsub;
nchan_channel_id "$1" "$2" "$3" "$4" "$5" "control";
nchan_publisher_upstream_request /alter;
}
Die dritte Zeile oben chan_publisher_upstream...
leitet eingehende pub
Anfragen an einen anderen Server weiter
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";
}
Auf dem anderen Server habe ich Nginx so eingerichtet, dass PHP index.php
im Stammordner des Servers ausgeführt wird.
<?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
?>
Soweit ich das beurteilen kann, habe ich die NChan-Anweisungen ziemlich gewissenhaft befolgt. Wenn ich jedoch versuche, diese Konfiguration zum Veröffentlichen auf dem jetzt definierten pubsub
Kanal zu verwenden, wird die Clientverbindung unerwartet geschlossen. Um diesen Test durchzuführen, verwende ich einige einfache 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);}
An diesem Punkt, wenn ich versuche, das Folgende auszugeben
connectPubSub();
sendMessage('Hello world!');
Ich erhalte die unten gezeigte Ausgabe
[open] Connection Established
Websocket connection to app.server.url failed:Close received after close
Das Fehlerereignis ist wie unten dargestellt
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
Das hat mich ratlos gemacht. Ich dachte, ich könnte einfach den NChan-Dokumenten folgen und Nachrichten auf dem Multiplex- pubsub
Kanal veröffentlichen und dann den Nachrichteninhalt (JSON) auf meinem Proxy-Server untersuchen, bevor ich entscheide, was zu tun ist
- Lassen Sie die Nachricht durch (geben Sie ein HTTP 304 aus)
- Ergreifen Sie serverseitige Maßnahmen und unterdrücken Sie dann die Nachricht (geben Sie ein HTTP 204 aus).
- Ändern Sie die Nachricht und senden Sie sie weiter (geben Sie ein HTTP 200 aus).
Meine eher lückenhaften Kenntnisse der Nginx-Konfigurationsanweisungen lassen mich hier wahrscheinlich im Stich. Was mache ich falsch?
Ich konnte nun feststellen, was hier vor sich geht. Die Wurzel des Problems scheint hier zu sein:
Proxy-Passwort https://example.com;
Richtlinie. Wenn ich es ändere in
proxy_pass https://example.com/index.php;
alles funktioniert wie erwartet. Mir ist jedoch immer noch nicht klar, warum das passiert. Oben in meiner Nginx-Standardkonfigurationsdatei stehen die Zeilen
server
{
root /path/to/root;
index index.php;
server_name example.com;
Ich dachte, die dritte Zeile oben index index.php
reicht im Grunde aus, um Nginx anzuweisen, index.php an jedem beliebigen Ordner/Unterordner auszuführen. Das ist aber offensichtlich nicht der Fall? [1]:https://nchan.io
[2]:https://nchan.io/#getting-started