具有套接字io节点js的图像

时间:2018-08-21 16:59:26

标签: node.js image socket.io

我正在尝试做听起来很简单的事情,但是很遗憾,我无法做到正确。

我只需要使用socket.io从文件流式传输图像。

我已经阅读了一些过时或不完整的链接,这是我现在的位置(不起作用):

server.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var bodyParser = require('body-parser');
var fs = require('fs');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));

app.get('/',function (req,res){res.sendStatus(200)});
app.get('/image',function (req,res){res.sendFile(__dirname+'/index.html')});


http.listen(3000, function () {
    console.log("server listening");
}); 

io.on('connection',function(socket){
    console.log("socket connection");
    var interval = setInterval(function(){
        fs.readFile('./image.jpeg',function(err,buff){
            if(err){
                console.error(err);
            }
            else{
                socket.emit('image',{image:true,buffer:buff.toString('base64')});
            }
        });
    },1000);
    socket.on('disconnect', function(){
        console.log("socket deconnection");
        clearInterval(interval);
    });
});

index.html

<html>
  <head>
    <meta charset="UTF-8">
    <title>IMAGE</title>
  </head>
  <body>
    <script src="/socket.io/socket.io.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <script>
      $(function(){
        var socket = io();
        var ctx = document.getElementById('canvas').getContext('2d');
        socket.on('image',function(info){
          if(info.image){
            var img = new Image();
            img.onload = function () {
              ctx.drawImage(img, 0, 0);
            };
            img.src = 'data:image/jpeg;base64,' + info.buffer;
            console.log("Image received");
          }
        })
      });
    </script>
  </body>
</html>

我还为客户端文件尝试了其他几种与此配置相似的配置,但是它们都不起作用。

我会定期读取文件,因为在实际项目中,image.jpeg文件有时会更改。

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

通过套接字发送图像不是很有效。当我不得不向每个客户发送大型游戏世界数据缓冲区时,我偶然发现了类似的情况。通过套接字连接发送这些数据包显然不是我的选择。

我解决了这一问题,方法是将引用到特定文件的密钥存储在服务器上,然后仅将该密钥发送给客户端。然后,客户端会将包含密钥的请求发送到http服务器,该服务器最终将对该文件做出响应。

这里有一些简短的代码只是为了说明:

在服务器上:

...
const files = {};
...

...
function (request, response) { // http request function
    const key = request.url.parse(key);

    const file = fs.readFile(files[key]);

    response.send(file);
}
...

...
function sendFile (socket, file) { // function that sends and stores the key
    const key = generateKey();
    files[key] = file;

    socket.send('key', key);
}
...

...
sendFile(socket, '/path/to/file'); // send key to socket
...

通过这种方式,可以通过http而不是套接字下载大文件。

在客户端上:

...
socket.on('key', function (key) {
    fetch('/file/' + key, function (response) {
        const file = response.blob(); // blob or whatever
    });
});
...

希望这对您有帮助:D