[node.js] uWebSockets.js 및 Websocket-Sharp와 함께 웹 소켓 압축 사용

연결을 위해 웹 소켓을 사용하는 모바일 게임이 있습니다. 서버는 uWebSockets.js 라이브러리를 사용하는 Node.js 앱 이고 클라이언트는 Websocket -Sharp 라이브러리를 사용하는 Unity 앱 입니다. 그들은 함께 잘 연주하고 우리는 그들과 문제가 발생하지 않았습니다.

최근에 우리는 websocket 압축 을 활성화하고 싶었습니다 . 두 라이브러리 모두 메시지 단위 압축 확장을 지원한다고 말했지만 호환되지 않는 것으로 보입니다. 압축을 사용하도록 구성하면 악수시 즉시 웹 소켓 연결이 닫힙니다.

우리는 또한 ws 라이브러리로 클라이언트를 테스트 했으며 동일한 결과를 가진 압축 예제를 제공했습니다. ws 압축 옵션을 사용하여 땜질을 시도한 결과 serverMaxWindowBits 옵션 (기본값은 협상 된 값)에 주석을 달면 연결이 설정 될 수 있으며 메시지 전송 및 수신이 문제없이 작동한다는 것을 알았습니다. 또한 uWebsockets에서 serverMaxWindowBits를 제어하는 ​​방법에 대해서도 질문 했습니다.

우리가 마지막으로 시도한 것은 최소한의 uWS 서버와 websocket-sharp 클라이언트를 연결하는 것입니다. 서버 코드는 다음과 같습니다.

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 소스 (uWebsockets.js 모듈의 C ++ 부분)를 검토 하고 server_no_context_takeover 헤더를 다시 전송하기위한 주석 처리 된 조건 을 찾았습니다 . 따라서 조건의 주석 처리를 제거하고 uWebsockets.js를 빌드하고 클라이언트에서 다음 오류가 발생하는지 다시 테스트했습니다.

WebSocketSharp.WebSocketException : 프레임의 헤더를 스트림에서 읽을 수 없습니다.

이 두 라이브러리를 함께 사용하기위한 제안 사항이 있습니까?



답변

업데이트 : 의 코드를 읽은 결과 압축을 사용하도록 설정 해야하는 uWebSockets.js모든 매개 변수를 사용하도록 변경해야합니다 websocket-sharp. 고성능 Java 서버 인 Vertx에서는 다음 설정이 Unity 호환 websocket-sharp압축에서 작동합니다.

vertx.createHttpServer(new HttpServerOptions()
                .setMaxWebsocketFrameSize(65536)
                .setWebsocketAllowServerNoContext(true)
                .setWebsocketPreferredClientNoContext(true)
                .setMaxWebsocketMessageSize(100 * 65536)
                .setPerFrameWebsocketCompressionSupported(true)
                .setPerMessageWebsocketCompressionSupported(true)
                .setCompressionSupported(true));

이전 :

오류는 실제이며, websocket-sharp만 지원 permessage-deflate하고 대신 DEDICATED_COMPRESSOR( compression: 2)를 사용하십시오.


답변