【问题标题】:Send socket.io response data to client from node.js server in gzip format以 gzip 格式从 node.js 服务器向客户端发送 socket.io 响应数据
【发布时间】:2013-05-10 06:15:22
【问题描述】:

我遇到的问题是我不知道如何判断我发送回客户端的数据是否以 gzip 格式压缩。从我看到的命令行查看我的服务器的输出:

debug - websocket writing 3:::{"result":1368673052397}
debug - websocket writing 3:::{"result":1368673053399}
...

在我看来,服务器正在以 ascii 格式编写响应,而不是在发送之前先对其进行压缩。

以下是我为产生这些结果而编写的示例。从我读到的内容来看,只要我设置了“浏览器客户端 gzip”,我的回复就应该被压缩发送。如果他们不是我该怎么做,如果我是我如何从服务器的调试信息中判断它们实际上是压缩响应。

当我启动服务器时,我在 BASH 中使用以下命令:

$ NODE_ENV=生产节点 app.js

var express = require('express'),
    http    = require('http');

var app     = express(),
    server  = http.createServer(app),
    io      = require('socket.io').listen(server);

io.configure('production', function() {
    io.enable('browser client minification');
    io.enable('browser client etag');
    io.enable('browser client gzip');
    io.set('log level', 3);
});

app.use(express.logger('dev'));

app.get('/', function(req, res) {
    res.send(
    "<script src='/socket.io/socket.io.js'></script>\n"+
    "<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'></script>\n"+
    "<script>\n"+
    "var socket=io.connect('http://127.0.0.1:3000');\n"+
    "socket.on('message', function(data) {\n"+
    "   $(\"h2\").text(data);\n"+
    "});\n"+
    "</script>\n"+
    "<h1>"+process.env.NODE_ENV+"</h1>\n"+
    "<h2></h2>\n"
    );
});

server.listen('3000');

io.sockets.on('connection', function(webSocket) {
    function whileLoop() {
        setTimeout(function() {
                var epoch = (new Date).getTime();
                var jsonData = "{\"result\":"+epoch+"}";
                webSocket.send(jsonData);
            whileLoop();
        }, 1000);
    }
    whileLoop();
});

【问题讨论】:

  • 您可以简单地压缩 json 并使用 zip.js 或 jszip 之类的库来扩展客户端上的字符串。
  • @dandavis 我下载了 jszip,我已经使用 zlib 在服务器端使用了 deflate 部分,我可以将压缩数据发送到经过 base64 编码的客户端,但我似乎无法弄清楚如何膨胀客户端上的 base64 编码响应。假设我使用的是 jszip 库,你能把 index.html 中的更新代码发给我吗?
  • 如果你在服务器上发送一些类似 base64(deflate(JSON.stringify(str))) 的东西,然后在客户端使用 JSON.parse(inflate(atob(data)))...

标签: javascript node.js express socket.io


【解决方案1】:

browser client gzip 选项为/socket.io/socket.io.js 提供的socket.io 脚本 启用gzip 压缩。它不会影响实际的 WebSocket 连接。

WebSocket 协议本身最近才添加了对通过套接字发送的数据压缩的支持。 Soket.io does not yet support compressionother node WebSocket servers 也没有。

老实说,由于您在示例中发送的数据量很少,压缩实际上会适得其反,因为它可能会增加通过网络发送的数据量。

【讨论】:

  • 在这个例子中是的,它没有必要。然而,这只是一个例子。在我的实际应用程序中,我发送回一个更长的 json 字符串,并且由于带宽限制需要压缩。
  • @BradSmith:不幸的是,你现在是 SOL,因为 socket.io 不支持 WebSocket 压缩。作为一种解决方法,您可以通过套接字发送“数据可用”消息,然后执行传统的 XHR 请求以获取实际的 JSON 数据,这些数据可以被压缩。
  • 或者使用客户端/服务器兼容的压缩库自己(解)压缩数据。
【解决方案2】:

支持socket.io 1.4 默认启用压缩。

【讨论】:

    【解决方案3】:

    在阅读了一些 cmets 之后,我决定查看 3rd 方库来处理客户端的解压缩,这导致我使用了 JSXCompressor。

    http://jsxgraph.uni-bayreuth.de/wp/jsxcompressor/

    JSXCompressor 将从服务器获取 base64 编码的 gzip 压缩数据并处理解压缩和解码。只需下载库并将其放在相应的文件夹中即可。

    在服务器端,我使用 zlib 来处理 gzip。

    var express = require('express'),
        http    = require('http')
        zlib    = require('zlib');
    
    var app     = express(),
        server  = http.createServer(app),
        io      = require('socket.io').listen(server);
    
    app.use(express.logger('dev'));
    app.use(express.static(__dirname + '/public'));
    
    app.get('/', function(req, res) {
        res.send(
        "<script src='/socket.io/socket.io.js'></script>\n"+
        "<script src='/java/jsxcompressor.min.js'></script>\n"+
        "<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'></script>\n"+
        "<script>\n"+
        "var socket=io.connect('http://127.0.0.1:3000');\n"+
        "socket.on('message', function(data) {\n"+
        "   var jsonData = JXG.decompress(data);"+
        "   $(\"h1\").text(jsonData);\n"+
        "});\n"+
        "</script>\n"+
        "<h1></h1>\n"
        );
    });
    
    server.listen('3000');
    
    io.sockets.on('connection', function(webSocket) {
        function whileLoop() {
            setTimeout(function() {
                    var epoch = (new Date).getTime();
                    var jsonData = "{\"result\":"+epoch+"}";
                    zlib.gzip(jsonData, function(err, buffer) {
                        webSocket.send(buffer.toString('base64'));
                    });
                whileLoop();
            }, 1000);
        }
        whileLoop();
    });
    

    【讨论】:

      【解决方案4】:

      现在默认启用压缩 (>1.4),另请参阅这篇文章以供参考:http://socket.io/blog/socket-io-1-4-0/

      【讨论】:

        猜你喜欢
        • 2011-10-05
        • 1970-01-01
        • 2018-10-19
        • 2015-04-25
        • 1970-01-01
        • 1970-01-01
        • 2018-11-06
        • 2021-01-26
        • 2013-01-03
        相关资源
        最近更新 更多