【问题标题】:How to send file to a particular user in nodejs如何在nodejs中将文件发送给特定用户
【发布时间】:2019-07-21 21:42:06
【问题描述】:

我正在 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");
    });

【问题讨论】:

    标签: node.js rest express socket.io


    【解决方案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]),并使用从前端发送的新 socketio 更新它sockets[data .username] = socket.id;.

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

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

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

    【讨论】:

    • 我是 socket.io 的新手。我在用户登录时建立了套接字,它在 /dashboard、/dashboard/gdrive 等其他链接上也能正常工作,但是当我刷新页面时用户会断开连接。我正在使用 history.push 导航到其他页面。
    • 还有一件事,我认为根据您的代码,两个客户端都必须在线共享文件,但我需要的是类似于 facebook 中的好友请求,即应通知接收者“有人与您共享了文件”,接收者是否在线无关紧要。
    • 贴出你试过的代码。所以我可以调查一下
    • @AnmolMiddha 我更新了答案。永远记得发布代码并一次提出一个问题。
    【解决方案2】:

    如果是非实时数据:

    服务器端-:

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

    客户端-:

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

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

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

    【讨论】:

      猜你喜欢
      • 2019-10-21
      • 2023-03-18
      • 1970-01-01
      • 2017-06-20
      • 2020-10-09
      • 1970-01-01
      • 2015-05-14
      • 2020-07-25
      • 1970-01-01
      相关资源
      最近更新 更多