简体   繁体   中英

Serving Images over Websockets with NodeJS & SocketIO

I am trying to develop a very simple image server with 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. 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.

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. 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. 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. 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.

EDIT: I suppose the real question here is, "are websockets really the best way to serve static files?" 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? 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.

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.

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.

So I would say that websockets aren't very suitable for static file serving :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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