Kami memiliki game seluler menggunakan websocket untuk koneksi. Server adalah aplikasi Node.js menggunakan pustaka uWebSockets.js dan klien adalah aplikasi Unity menggunakan pustaka Websocket-Sharp . Mereka berdua bermain bersama dengan baik dan kami tidak mengalami masalah dengan mereka.
Baru-baru ini kami ingin mengaktifkan kompresi websocket . Kedua perpustakaan menyatakan bahwa mereka mendukung ekstensi Kompresi Per-pesan tetapi tampaknya ada sesuatu yang tidak kompatibel dengan mereka. Karena ketika kita mengkonfigurasi untuk menggunakan kompresi, koneksi websocket segera ditutup pada jabat tangan.
Kami juga menguji klien dengan pustaka ws dan ini memberikan contoh untuk kompresi dengan hasil yang sama. Kami mencoba bermain-main dengan opsi kompresi dan menemukan bahwa ketika kami mengomentari opsi serverMaxWindowBits (default untuk nilai negosiasi) koneksi dapat dibuat dan mengirim dan menerima pesan berfungsi tanpa masalah. Kami juga bertanya tentang cara mengontrol serverMaxWindowBits di uWebsockets.
Hal terakhir yang kami coba adalah menghubungkan server uWS minimal dan klien websocket-tajam. Berikut adalah kode untuk 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);
}
});
Berikut adalah kode klien:
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);
}
}
}
}
Ketika kami menjalankan server dan klien, klien memancarkan kesalahan berikut:
Kesalahan | WebSocket.checkHandshakeResponse | Server belum mengirim kembali 'server_no_context_takeover'. Fatal | WebSocket.doHandshake | Termasuk header Sec-WebSocket-Extensions yang tidak valid.
Tampaknya header server_no_context_takeover klien diharapkan dan tidak menerima satu. Kami meninjau sumber uWebsockets (bagian C ++ dari modul uWebsockets.js) dan menemukan kondisi yang dikomentari untuk mengirim kembali header server_no_context_takeover. Jadi kami membatalkan komentar kondisi dan membangun uWebsockets.js dan menguji lagi untuk menemukan kesalahan berikut di klien:
WebSocketSharp.WebSocketException: Header suatu frame tidak dapat dibaca dari stream.
Adakah saran untuk membuat kedua perpustakaan ini bekerja bersama?
Jawaban:
Pembaruan: Berdasarkan pembacaan saya terhadap kode
uWebSockets.js
, perubahan harus dilakukan untuk mengaktifkan semua parameter yangwebsocket-sharp
perlu diatur untuk mengaktifkan kompresi. Di Vertx, server Java berkinerja tinggi, pengaturan berikut ini berfungsi dengan Unity-compatiblewebsocket-sharp
untuk kompresi:Sebelumnya:
Kesalahan itu nyata,
websocket-sharp
hanya mendukungpermessage-deflate
, gunakanDEDICATED_COMPRESSOR
(compression: 2
) sebagai gantinya.sumber
WebSocket.cs
penolakan tajuk?DEDICATED_COMPRESSOR
benar-benar harus bekerja!