在uWebSockets.js和Websocket-Sharp中使用websocket压缩

时间:2019-12-04 16:10:19

标签: node.js unity3d websocket websocket-sharp uwebsockets

我们有一个使用websocket进行连接的手机游戏。服务器是使用uWebSockets.js库的Node.js应用程序,客户端是使用Websocket-Sharp库的Unity应用程序。他们俩在一起玩的很好,我们没有遇到任何问题。

最近,我们想启用 websocket压缩。这两个库都声明它们支持按消息压缩扩展,但似乎有些东西与它们不兼容。因为当我们配置为使用压缩时,Websocket连接在握手时立即关闭。

我们还使用ws库测试了客户端,并提供了压缩效果相同的示例。我们尝试修改ws压缩选项,发现在注释serverMaxWindowBits选项(默认为协商值)时,可以建立连接,并且发送和接收消息也可以正常工作。我们还asked关于控制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 ++部分),发现了一个commented condition用于发送回server_no_context_takeover标头。因此,我们取消注释条件,并构建了uWebsockets.js并再次进行了测试,以在客户端中遇到以下错误:

  

WebSocketSharp.WebSocketException:无法从流中读取帧的头。

关于使这两个库协同工作的任何建议?

2 个答案:

答案 0 :(得分: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_COMPRESSORcompression: 2)。

答案 1 :(得分:0)

无法评论信誉低下的问题:(

您需要在项目更改中包含uws.js

此常量uWS = require('uWebSockets.js');const uWS = require('uws.js'); 您可以在此处下载uws.jshttps://github.com/uNetworking/uWebSockets.js/blob/master/src/uws.js

这是工作示例:

const uWS = require('../dist/uws.js');
const port = 9001;

const app = uWS./*SSL*/App({
  key_file_name: 'misc/key.pem',
  cert_file_name: 'misc/cert.pem',
  passphrase: '1234'
}).ws('/*', {
  /* Options */
  compression: 0,
  maxPayloadLength: 16 * 1024 * 1024,
  idleTimeout: 10,
  /* Handlers */
  open: (ws, req) => {
    console.log('A WebSocket connected via URL: ' + req.getUrl() + '!');
  },
  message: (ws, message, isBinary) => {
    /* Ok is false if backpressure was built up, wait for drain */
    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);
  }
});

您可以在此处找到更多示例: https://github.com/uNetworking/uWebSockets.js/tree/master/examples

  

注意:旧版本不支持node.js,因此请使用最新版本