Abbiamo un gioco mobile che utilizza websocket per le connessioni. Il server è un'app Node.js che utilizza la libreria uWebSockets.js e il client è un'app Unity che utilizza la libreria Websocket-Sharp . Entrambi giocano bene insieme e non abbiamo riscontrato problemi con loro.
Recentemente abbiamo voluto abilitare la compressione del websocket . Entrambe le librerie hanno dichiarato di supportare l'estensione di compressione per messaggio, ma sembra che ci sia qualcosa di incompatibile con loro. Perché quando configuriamo l'uso della compressione, la connessione al websocket si chiude immediatamente in stretta di mano.
Abbiamo anche testato il client con la libreria ws ed è fornito un esempio per la compressione con lo stesso risultato. Abbiamo provato ad armeggiare con le opzioni di compressione ws e abbiamo scoperto che quando commentiamo l'opzione serverMaxWindowBits (il valore predefinito è negoziato), la connessione potrebbe essere stabilita e l'invio e la ricezione di messaggi funziona senza problemi. Abbiamo anche chiesto informazioni sul controllo di serverMaxWindowBits in uWebsocket.
L'ultima cosa che abbiamo provato è stata la connessione di un server uWS minimo e di un client nitido. Ecco il codice per il 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);
}
});
Ecco il codice client:
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);
}
}
}
}
Quando abbiamo eseguito il server e il client, il client emette il seguente errore:
Errore | WebSocket.checkHandshakeResponse | Il server non ha inviato indietro 'server_no_context_takeover'. Fatal | WebSocket.doHandshake | Include un'intestazione Sec-WebSocket-Extensions non valida.
Sembrava che il client si aspettasse un'intestazione server_no_context_takeover e non ne avesse ricevuta una. Abbiamo esaminato l' origine uWebsockets (parte C ++ del modulo uWebsockets.js) e trovato una condizione commentata per l'invio di intestazione server_no_context_takeover. Quindi abbiamo decommentato la condizione e creato uWebsockets.js e testato di nuovo per riscontrare il seguente errore nel client:
WebSocketSharp.WebSocketException: l'intestazione di un frame non può essere letta dal flusso.
Qualche suggerimento per far lavorare insieme queste due librerie?