简体   繁体   English

使用NodeJS和SocketIO通过Websockets提供图像

[英]Serving Images over Websockets with NodeJS & SocketIO

I am trying to develop a very simple image server with NodeJS & SocketIO. 我正在尝试使用NodeJS和SocketIO开发一个非常简单的图像服务器。 A project I am working on requires me to load several hundred images on page-load (customer requirement). 我正在从事的项目要求我在页面加载(客户需求)时加载几百张图像。 Currently, a HTTP request is made for each image via use of the HTML "img" tag. 当前,通过使用HTML“ img”标签为每个图像发出HTTP请求。 With the reduced latency and overall efficiency of websockets compared to HTTP or Ajax, I was hoping to improve performance by sending images over websockets instead. 与HTTP或Ajax相比,Websocket的延迟减少了,整体效率降低了,我希望通过在Websocket上发送图像来提高性能。

Unfortunately, reading images from the server's file-system with NodeJS and sending them over websockets with SocketIO has been significantly slower than the traditional HTTP requests served over Apache. 不幸的是,使用NodeJS从服务器的文件系统中读取图像并使用SocketIO通过websocket发送图像的速度明显慢于通过Apache服务的传统HTTP请求。 Below is my server code: 下面是我的服务器代码:

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

server.listen(151);

io.sockets.on('connection',function(socket){
    socket.emit('connected');

    socket.on('getImageData',function(file,callback){
        var path = 'c:/restricted_dir/'+file;

        fs.readFile(path,function(err,data){
            if (!err){
                var prefix = "data:" + mime.lookup(path) + ";base64,";
                var base64Image = prefix+data.toString('base64');
                socket.emit('imageData',data,callback);
            }
        });
    });
});

I have also tried buffering with "createReadStream", but I saw no significant speed improvements with this. 我也尝试过使用“ createReadStream”进行缓冲,但是我发现此操作没有明显的速度改进。 I should also note that it is desirable to receive the image data as a Base64-encoded dataURI so I can simply throw that into the "src" attribute of the "img" tag. 我还应注意,希望以Base64编码的dataURI形式接收图像数据,因此我可以将其简单地放入“ img”标签的“ src”属性中。 I understand Base64 means roughly a 30% increase in the data's size, but even when using binary image data, it still takes about 10 times longer than HTTP. 我知道Base64意味着数据大小大约增加了30%,但是即使使用二进制图像数据,它仍然比HTTP花费大约10倍的时间。

EDIT: I suppose the real question here is, "are websockets really the best way to serve static files?" 编辑:我想这里的真正问题是,“ websockets确实是服务静态文件的最佳方法吗?” After further thought and additional reading, I strongly suspect the issue here is related to parallel processing. 经过进一步的思考和补充阅读,我强烈怀疑这里的问题与并行处理有关。 Since NodeJS operates on a single thread, maybe it is not the best solution for serving all these static image files? 由于NodeJS在单个线程上运行,因此它不是服务所有这些静态图像文件的最佳解决方案吗? Does anyone have any thoughts on this? 有人对此有任何想法吗?

Browsers usually open multiple connections to the same server to perform requests in parallel, and can also perform multiple requests per single connection , whereas you only have one websocket connection. 浏览器通常打开到同一服务器的多个连接以并行执行请求,并且每个连接也可以执行多个请求 ,而您只有一个websocket连接。

Also, the combo fs.readFile()/Base64-encode/socket.emit() introduces a significant overhead, where a regular httpd can use system calls like sendfile() and don't even have to touch the file contents before they are being sent to the client. 同样,组合fs.readFile()/Base64-encode/socket.emit()引入了相当大的开销,在这种情况下,常规的httpd可以使用sendfile()类的系统调用,甚至不必先触摸文件内容即可。被发送到客户端。

The single-threaded nature of Node isn't an issue here, because Node can do I/O (which is what you're doing, minus the Base64-encoding) really well. Node的单线程性质在这里不是问题,因为Node可以很好地执行I / O(这就是您正在做的事情,减去Base64编码)。

So I would say that websockets aren't very suitable for static file serving :) 所以我想说websockets不太适合静态文件服务:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM