У нас есть мобильная игра, использующая веб-сокет для соединений. Сервер представляет собой приложение Node.js, использующее библиотеку uWebSockets.js, а клиент - приложение Unity, использующее библиотеку Websocket-Sharp . Они оба хорошо играют вместе, и мы не столкнулись с проблемой с ними.
Недавно мы хотели включить сжатие websocket . Обе библиотеки заявили, что они поддерживают расширение сжатия сообщений, но, похоже, что-то несовместимо с ними. Потому что, когда мы настраиваем использовать сжатие, соединение веб-сокета немедленно закрывается при рукопожатии.
Мы также проверили клиент с библиотекой ws и предоставили пример для сжатия с тем же результатом. Мы попытались изменить параметры сжатия ws и обнаружили, что когда мы комментируем параметр serverMaxWindowBits (по умолчанию это согласованное значение), соединение может быть установлено, и отправка и получение сообщений работают без проблем. Мы также спросили об управлении serverMaxWindowBits в uWebsockets.
Последнее, что мы попробовали, - это подключение минимального сервера uWS и клиента с поддержкой веб-сокетов. Вот код для сервера:
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);
}
});
Вот код клиента:
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);
}
}
}
}
Когда мы запустили сервер и клиент, клиент выдаст следующую ошибку:
Ошибка | WebSocket.checkHandshakeResponse | Сервер не отправил обратно «server_no_context_takeover». Fatal | WebSocket.doHandshake | Содержит недопустимый заголовок Sec-WebSocket-Extensions.
Казалось, что клиент ожидал заголовок server_no_context_takeover и не получил его. Мы рассмотрели источник uWebsockets (часть C ++ модуля uWebsockets.js) и обнаружили закомментированное условие для отправки заголовка server_no_context_takeover. Поэтому мы раскомментировали условие и создали файл uWebsockets.js и снова протестировали его на наличие следующей ошибки в клиенте:
WebSocketSharp.WebSocketException: заголовок фрейма не может быть прочитан из потока.
Любые предложения для совместной работы этих двух библиотек?
Ответы:
Обновление: основываясь на моем чтении кода
uWebSockets.js
, необходимо внести изменения, чтобы включить все параметры,websocket-sharp
необходимые для включения сжатия. В высокопроизводительном Java-сервере Vertx следующие параметры работают с Unity-совместимымwebsocket-sharp
для сжатия:Ранее:
Ошибка реальна,
websocket-sharp
только поддерживаетpermessage-deflate
, используйте вместо нееDEDICATED_COMPRESSOR
(compression: 2
).источник
WebSocket.cs
отклонения заголовка в России?DEDICATED_COMPRESSOR
действительно должно работать!