Wir haben ein Handyspiel, das Websocket für Verbindungen verwendet. Der Server ist eine Node.js-App, die die Bibliothek uWebSockets.js verwendet, und der Client ist eine Unity-App, die die Websocket-Sharp- Bibliothek verwendet. Beide spielen gut zusammen und wir hatten kein Problem mit ihnen.
Kürzlich wollten wir die Websocket-Komprimierung aktivieren . Beide Bibliotheken gaben an, dass sie die Erweiterung für die Komprimierung pro Nachricht unterstützen, aber es scheint, dass etwas mit ihnen nicht kompatibel ist. Denn wenn wir die Komprimierung konfigurieren, wird die Websocket-Verbindung beim Handshake sofort geschlossen.
Wir haben auch den Client mit der ws- Bibliothek getestet und es wird ein Beispiel für die Komprimierung mit demselben Ergebnis bereitgestellt. Wir haben versucht, an den ws-Komprimierungsoptionen zu basteln, und festgestellt, dass beim Kommentieren der Option serverMaxWindowBits (standardmäßig der ausgehandelte Wert) die Verbindung hergestellt werden konnte und das Senden und Empfangen von Nachrichten problemlos funktioniert. Wir haben auch nach der Steuerung der serverMaxWindowBits in uWebsockets gefragt.
Das letzte, was wir versucht haben, war die Verbindung eines minimalen uWS-Servers und eines websocketscharfen Clients. Hier ist der Code für den Server:
const uWS = require('uWebSockets.js');
const port = 5001;
const app = uWS.App({
}).ws('/*', {
/* Options */
compression: 1, // Setting shared compression method
maxPayloadLength: 4 * 1024,
idleTimeout: 1000,
/* Handlers */
open: (ws, req) => {
console.log('A WebSocket connected via URL: ' + req.getUrl() + '!');
},
message: (ws, message, isBinary) => {
/* echo every message received */
let ok = ws.send(message, isBinary);
},
drain: (ws) => {
console.log('WebSocket backpressure: ' + ws.getBufferedAmount());
},
close: (ws, code, message) => {
console.log('WebSocket closed');
}
}).any('/*', (res, req) => {
res.end('Nothing to see here!');
}).listen(port, (token) => {
if (token) {
console.log('Listening to port ' + port);
} else {
console.log('Failed to listen to port ' + port);
}
});
Hier ist der Client-Code:
using System;
using WebSocketSharp;
namespace Example
{
public class Program
{
public static void Main (string[] args)
{
using (var ws = new WebSocket ("ws://localhost:5001")) {
ws.OnMessage += (sender, e) =>
Console.WriteLine ("server says: " + e.Data);
ws.Compression = CompressionMethod.Deflate; // Turning on compression
ws.Connect ();
ws.Send ("{\"comm\":\"example\"}");
Console.ReadKey (true);
}
}
}
}
Wenn wir den Server und den Client ausgeführt haben, gibt der Client den folgenden Fehler aus:
Fehler | WebSocket.checkHandshakeResponse | Der Server hat 'server_no_context_takeover' nicht zurückgesendet. Fatal | WebSocket.doHandshake | Enthält einen ungültigen Sec-WebSocket-Extensions-Header.
Es schien, dass der Client den Header server_no_context_takeover erwartet und keinen erhalten hat. Wir haben die uWebsockets- Quelle (C ++ - Teil des Moduls uWebsockets.js) überprüft und eine kommentierte Bedingung für das Zurücksenden des Headers server_no_context_takeover gefunden. Also haben wir die Bedingung auskommentiert und uWebsockets.js erstellt und erneut getestet, um den folgenden Fehler im Client zu finden:
WebSocketSharp.WebSocketException: Der Header eines Frames kann nicht aus dem Stream gelesen werden.
Irgendwelche Vorschläge, wie diese beiden Bibliotheken zusammenarbeiten können?
Antworten:
Update: Basierend auf dem Einlesen des Codes in
uWebSockets.js
müssten Änderungen vorgenommen werden, um alle Parameterwebsocket-sharp
zu aktivieren, die zum Aktivieren der Komprimierung erforderlich sind. In Vertx, einem Hochleistungs-Java-Server, funktionieren die folgenden Einstellungen mit Unity-kompatibelwebsocket-sharp
für die Komprimierung:Vorher:
Der Fehler ist real,
websocket-sharp
unterstützt nurpermessage-deflate
, verwenden Sie stattdessenDEDICATED_COMPRESSOR
(compression: 2
).quelle
WebSocket.cs
Header-Zurückweisung reproduziert ?DEDICATED_COMPRESSOR
sollte wirklich funktionieren!