UWebSockets.js ve Websocket-Sharp ile websocket sıkıştırmasını kullanma


11

Bağlantılar için websocket kullanan bir mobil oyunumuz var. Sunucu uWebSockets.js kitaplığını kullanan bir Node.js uygulaması ve istemci Websocket-Sharp kitaplığını kullanan bir Unity uygulamasıdır . İkisi birlikte iyi oynuyor ve onlarla bir sorunla karşılaşmadık.

Son zamanlarda websocket sıkıştırmasını etkinleştirmek istedik . Her iki kütüphane de İleti Başına Sıkıştırma uzantısını desteklediklerini, ancak onlarla uyumsuz bir şey olduğu anlaşılıyor. Çünkü sıkıştırma kullanacak şekilde yapılandırdığımızda websocket bağlantısı el sıkışmasında hemen kapanır.

Ayrıca istemciyi ws kütüphanesi ile test ettik ve aynı sonuçla sıkıştırma için örnek sağlandı. Ws sıkıştırma seçenekleriyle uğraşmayı denedik ve serverMaxWindowBits seçeneğini (varsayılan olarak anlaşılan değer) yorum yaptığımızda bağlantının kurulabileceğini ve mesaj alıp göndermenin sorunsuz çalıştığını gördük. Ayrıca uWebsockets içindeki serverMaxWindowBits öğelerini denetleme hakkında da sorduk .

Denediğimiz son şey, minimal bir uWS sunucusu ve websocket-sharp istemcisi bağlamaktı. Sunucunun kodu şöyledir:

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);
        }
    });

İstemci kodu şöyledir:

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);
      }
    }
  }
}

Sunucuyu ve istemciyi çalıştırdığımızda, istemci aşağıdaki hatayı yayar:

Hata | WebSocket.checkHandshakeResponse | Sunucu 'server_no_context_takeover' öğesini geri göndermedi. Fatal | WebSocket.doHandshake | Geçersiz bir Sec-WebSocket-Extensions üstbilgisi içerir.

İstemcinin server_no_context_takeover üstbilgisini beklediği ve bir tane almadığı anlaşılıyor. Biz gözden uWebsockets kaynağını (uWebsockets.js modülünün C ++ parçası) ve bir tespit yorumladı koşulu geri server_no_context_takeover başlığını göndermek için. Bu nedenle durumu çözdük ve uWebsockets.js'yi oluşturduk ve istemcide aşağıdaki hatayla karşılaşmak için tekrar test ettik:

WebSocketSharp.WebSocketException: Bir çerçevenin başlığı akıştan okunamıyor.

Bu iki kütüphanenin birlikte çalışması için herhangi bir öneriniz var mı?


Hiç yardımcı olmadığından emin değilim, ama socket.io varsayılan olarak sıkıştırıyor. Bildiğim En HTTP 2 socket.io için vardır oldukça iyi destek - Yuvalarının.
Samuel G

@SamuelG Teşekkürler, ancak şu anda minimum kaynaklarla 5k + eşzamanlı bağlantıyı ele aldığımız için socket.io kullanmak bir seçenek değildir.
Koorosh Pasokhi

@KooroshPasokhi socket.io'nun yükünüzü kaldıramayacağı ya da kaynak yoğun olduğu yönündeki gerekçenizi sonuçlandıran nedir? Testleriniz hakkında daha fazla bilgi almak isterim.
Samuel G

@SamuelG Yorumlar tartışmalar için değildir, ancak diyelim ki ana nedenler socket.io'nun odak noktası performans değildir ve socket.io'da daha yüksek katman soyutlamalarına ihtiyacımız yoktur.
Koorosh Pasokhi

Yanıtlar:


3

Güncelleme: Kodu okuduğuma göre, sıkıştırmayı etkinleştirmek için ayarlanması gereken uWebSockets.jstüm parametrelerin etkinleştirilmesi için değişikliklerin yapılması gerekiyordu websocket-sharp. Yüksek performanslı bir Java sunucusu olan Vertx'te aşağıdaki ayarlar websocket-sharpsıkıştırma için Unity uyumludur :

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

Önceden:

Hata gerçek, websocket-sharpsadece destekler permessage-deflate, bunun yerine DEDICATED_COMPRESSOR( compression: 2) kullanın.


Ne yazık ki sıkıştırma yöntemini 2 olarak ayarlamak hata mesajını değiştirmedi :(
Koorosh Pasokhi

Sonra uWebSockets ile ilgili bir sorun var. Java'nın vertx websockets'ı daha fazla yapılandırma alanına sahip istemcide WebSocketSharp ile sıkıştırma ile kullanıyorum ve sadece çalışıyor.
DoctorPangloss

Belki doğrudan uWebSockets.js dosyasında WebSocket.csbaşlık reddinin davranışını yeniden üreten bir test yazmayı deneyin ? DEDICATED_COMPRESSORgerçekten çalışmalı!
DoctorPangloss

Ne demek istiyorsun? UWebSockets.js'nin mimarisi biraz karmaşıktır. Hata ayıklamayı zorlaştıran JS, C ++ ve C'de yazılmış üç katmanı vardır.
Koorosh Pasokhi

Yani, uyumlu bir sunucuya bağlayarak ve ne olduğunu görerek bulabileceğiniz el sıkışması websocket-sharp'u yeniden üreten uWebSockets.js proje dizininde bir test yazmak demek?
DoctorPangloss
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.