如何在Node.js中将文件发送给特定用户

时间:2019-02-28 03:09:22

标签: node.js rest express socket.io

我正在nodejs上创建一个rest api。我在数据库中有电子邮件ID和用户ID。我想从一个用户到一个特定用户共享一个文件(存在于同一服务器上)。谁能告诉我最好的方法吗?

这是我尝试过的代码。

const server = require('./../server/server.js')
const socketIO = require('socket.io');
const io = socketIO(server);
const mongoose = require('mongoose');

const User = require('../models/user.js');
let sockets = [];

    io.on('connection', socket=>{
    console.log("User connected");

    socket.on('online', (data)=>{
        socket.name = data._id;
        sockets[data._id] = socket.id;
        console.log("user is online")
    })

    socket.on('send_file', (data)=>{
        User.find({emailId: data},{emailId:0, password:0})
        .exec()
        .then(userid => {
            if(userid.length<1){
            console.log("No such user");
            }
            else{
                console.log(userid[0].id);
                socket.to(sockets[userid[0].id]).emit('hello', "HELLO");
            }
        })
        .catch(err =>{
        console.log(err);
        });
    });

    socket.on('disconnect', ()=>{
        console.log("User disconnected");
    })
    })

    module.exports = io;

    server.listen('8080', (err)=>{
        if(err) throw err;
        console.log("running on port 8080");
    });

2 个答案:

答案 0 :(得分:1)

假设您已经配置了socketio并使用将文件路径和文件名保存在数据库中的机制正确地表达了服务器

尝试这种方法(使用socketio)

let sockets = [];

    io.on("connection", function(socket) {
      socket.on("online", data => {
        socket.name = data.username;
        sockets[data.username] = socket.id;
      });

      socket.on("send_file", function(data) {
        // your logic to retrieve the file path from you database in to the variable **filedata** 
        // let filedata = ................
        socket.to(sockets[data.user]).emit("file",filedata);
      });

      socket.on("disconnect", reason => {
        sockets.splice(sockets.findIndex(id => id === socket.id), 1);
      });

    });

在send_file事件中,您将从数据对象内部的发送者那里收到用户名。以下代码将帮助您将文件发送给选定的用户。

socket.to(sockets [data.user])。emit(“ file”,filedata);

回复您的第一条评论

history.push()将不会刷新客户端,因为它是单页应用程序。 但是当您刷新(从用户 A 端)时,将创建一个新的套接字会话,然后另一个用户(用户 B )仍将引用旧的套接字会话(即已通过刷新断开连接)。因此,使用以下几行

 socket.on("online", data => {
    socket.name = data.username;
    sockets[data.username] = socket.id;
  });

您将使用用户名保留sockets的池(数组),因此,当用户刷新其客户端时,新创建的套接字将引用同一用户。因为您将把socket.id更新为同一个人。 例如,假设您是刷新客户端的用户,而另一个用户。因此,当您刷新新的套接字会话时,它将创建一个套接字会话,并将其与用户名一起发送到后端。当数据到达服务器时,它将从数组( sockets [data.username] )获取您的会话对象,并使用从您的前端 sockets [data]发送的新套接字更新它.username] = socket.id;

为此,您必须将用户名与套接字消息一起发送。像这样

socket.emit("online", {
  username: "username"
});

回复您的第二条评论 为了实时发送数据,用户应该在线。如果不是,您可以只创建带有以下信息的通知数组(发送者和接收者)。因此,当接收者登录或单击通知面板时,可以显示共享文件通知列表。这只是一个建议,您可以提出自己的想法。希望这会有所帮助。

答案 1 :(得分:0)

对于非实时数据:

服务器端-:

使用res.sendFile()是解决此问题的一种方法。除了文件,还发送标头中的接收方和发送方ID

客户端-:

如果接收者ID与登录用户匹配,则增加通知计数。

res.sendFile(path.join("path to file"),
            {headers:{
                    receiverid:result[0]._id,
                    senderid:result[1]._id
                }
            });

对于实时数据: 遵循TRomesh发布的答案