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

问题描述 投票:0回答:2

我正在 Node.js 中创建一个 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");
    });
node.js rest express socket.io
2个回答
1
投票

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

尝试这样的事情(使用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("文件",filedata);

回复您的第一条评论

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

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

您将在其中保留带有用户名的

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

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

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

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


0
投票

如果是非实时数据:

服务器端-:

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

客户端-:

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

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

如果是实时数据: 按照 TRomesh 发布的答案

© www.soinside.com 2019 - 2024. All rights reserved.