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


11

연결을 위해 웹 소켓을 사용하는 모바일 게임이 있습니다. 서버는 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 : 프레임의 헤더를 스트림에서 읽을 수 없습니다.

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


전혀 도움이되지 않지만 socket.io는 기본적으로 압축됩니다. 나는 Best HTTP 2 가 socket.io-websockets를 꽤 잘 지원한다는 것을 알고 있습니다.
Samuel G

@SamuelG 감사하지만 현재 최소 리소스로 5k + 동시 연결을 처리하고 있기 때문에 socket.io를 사용하는 것은 옵션이 아닙니다.
Koorosh Pasokhi

@KooroshPasokhi socket.io 가로 드를 처리 할 수 ​​없거나 리소스 집약적이라고 추론 한 결론은 무엇입니까? 당신의 테스트에 대해 더 듣고 싶어요.
Samuel G

@SamuelG 의견은 토론을위한 것이 아니라, 주된 이유는 socket.io의 초점이며 성능이 아니고 socket.io에서 상위 계층 추상화가 필요하지 않다고 가정 해 봅시다.
Koorosh Pasokhi 2014

답변:


3

업데이트 : 의 코드를 읽은 결과 압축을 사용하도록 설정 해야하는 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)를 사용하십시오.


불행하게도 :( 오류 메시지를 변경하지 않은 2로 압축 방법을 설정
Koorosh Pasokhi

그런 다음 uWebSockets에 몇 가지 근본적인 문제가 있습니다. 더 많은 구성 필드가있는 클라이언트에서 WebSocketSharp로 압축하여 Java의 vertx 웹 소켓을 사용하며 작동합니다.
DoctorPangloss 19

WebSocket.cs의 헤더 거부 동작을 재현하는 uWebSockets.js에서 직접 테스트를 작성해보십시오 . DEDICATED_COMPRESSOR정말 작동합니다!
DoctorPangloss 19

무슨 시험인가요? uWebSockets.js의 아키텍처는 약간 복잡합니다. JS, C ++ 및 C로 작성된 세 개의 계층이 있으므로 디버깅이 어렵습니다.
Koorosh Pasokhi 2014

uWebSockets.js 프로젝트 디렉토리에서 악수 websocket-sharp가 수행하는 테스트를 작성하는 것을 의미합니다.이 서버는 호환되는 서버에 연결하여 어떤 일이 발생하는지 확인할 수 있습니까?
DoctorPangloss '12
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.