【问题标题】:Proper way to add a friend route in node.js and mongoose?在 node.js 和猫鼬中添加朋友路线的正确方法?
【发布时间】:2015-09-01 11:33:43
【问题描述】:

我打算创建一个用户可以添加另一个用户作为他/她的朋友的路线,这样他们一旦成为朋友就可以互相聊天。

所以基本上一旦用户 A 向用户 B 发送请求,用户 B 将通过socket.io 收到有关该请求的实时通知

现在的问题是,我无法想出自己的解决方案来实现上述场景,据我所知,我应该创建两条路由GETPOST

我正在使用 mongoose 进行数据库查询、插入、更新和删除

这是我的代码

// GET route for getting the user's information -- Simple route

router.get('/users/:facebook_name', function(req, res) {
  User.findOne(facebook_name, function(err, user) {
    if (!user) {
      res.json({message: "Couldn't find a user by that name"});
      return;
    } 
    res.json(user);
  });
});

// POST route for adding a friend 
router.post('/friendships/create/:facebook_name', ensureAuthenticated, function(req, res) {
  // What should i put in this route to make the adding a friend feature works?
  User.findOneAndUpdate(facebook_name, function(err, user) {  
    if (user) {
      res.json({message: "You already send a friend request to that person"});
      return;
    } 
    // Send a live notification to the other user
    socket.emit('sending request', {message: "added you as a friend"});
  }); 
});

用户架构代码 -- 也不确定这个

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = new Schema({

  friends: [{ type: Schema.Types.ObjectId, ref: 'User'}],
  facebook: {
    id: String,
    token: String,
    // email: String,
    displayName: String,
    photo: String
  }
});

// Should I even create this schema?
var FriendsRequest = new Schema({

  madeBy: [{ type: Schema.Types.ObjectId, ref: 'User'}],


})

module.exports = mongoose.model('User', UserSchema);
module.exports = mongoose.model('FriendsRequest', FriendsRequest);

我对你们并不完全诚实,在POST 路由中,我对如何编写逻辑一无所知,因为我现在真的很困惑,用户 B 将如何获得实时请求通知?我应该为此创建另一条路线吗?

这是我在构建稍微复杂的应用程序时遇到的问题,我只是想不出一个好的逻辑来说明如何执行某个功能,即使它看起来很简单。我已经被这个问题困住了将近 4 个小时,浏览和阅读网络,但我相信 SO 是我唯一能找到如何做某事的线索的地方。

谢谢。

【问题讨论】:

    标签: node.js express mongoose socket.io


    【解决方案1】:

    您可以做的是为每个 facebookName(如果唯一)创建套接字。

    在客户端:

    socket.on('connection', function (data) {
       socket.emit('setFacebookName', facebookName); });
    }
    

    服务器使用 facebookName 保存每个套接字:

    socket.on('setFacebookName', function (facebookName) {
        users[facebookName]=socket;
    });
    

    现在,当用户在此请求中向该用户发送聊天请求时

    // POST route for adding a friend 
    router.post('/friendships/create/:facebook_name', ensureAuthenticated, function(req, res) {
      // What should i put in this route to make the adding a friend feature works?
      User.findOneAndUpdate(facebook_name, function(err, user) {  
        if (user) {
          res.json({message: "You already send a friend request to that person"});
          return;
        } 
        // Send a live notification to the other user
        sendLiveNotification(facebook_name);
      }); 
    });
    
    function sendLiveNotification(facebookName){
       socket.on('send notification', function (facebookName) {
         users[facebookName].emit('sending request', "has sent friend request");
       });
    }
    

    【讨论】:

    • 只是想知道用户变量代表什么?我如何创建它们?
    • 而其他用户如何接受好友的请求并将其保存到数据库中?当它符合条件时,将把这个问题作为 50 赏金。请详细说明
    • 看问题的更新版本,我加了一些数据库文件
    • users 变量我猜它必须在某个数据库中,比如redis,因为如果您拥有的不仅仅是一台服务器,那么这种方法就会出现问题。其中一部分是,如果用户不在线,您将无法与他联系 + 如果用户从多个选项卡在线,他只会收到一次消息。您应该将用户与 sessionID 相关联,或者如果您想使用 facebook 名称,您应该创建一个套接字数组,而不仅仅是一个套接字。
    【解决方案2】:

    您正在尝试执行两步流程,因此您至少需要两次调用,其中一个是来自请求者的请求,另一个是决定是否允许来自被请求者的请求。您可以使用布尔值处理第一个函数的回调,如果它是一个新请求,则可以在客户端弹出一个提示用户。

    Mongoose 的一个很好的用途是您可以对 Schema 进行扩展,因此我在这里添加两个功能:一个来自请求者请求被请求者的友谊,另一个来自被请求者的决定

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    
    var UserSchema = new Schema({
    
      friendsAccepted: [{ type: Schema.Types.ObjectId, ref: 'User'}],
      friendsRequested: [{ type: Schema.Types.ObjectId, ref: 'User'}],
      friendsPending: [{ type: Schema.Types.ObjectId, ref: 'User'}],
      friendsRejected: [{ type: Schema.Types.ObjectId, ref: 'User'}],
      facebook: {
        id: String,
        token: String,
        // email: String,
        displayName: String,
        photo: String
      }
    });
    
    
    
    UserSchema.statics.requesterInitiatedRequestForFriendship = function(requesterID, requesteeID, cb) {
        mongoose.model('UserSchema').findOne({_id: requesterID}).exec(function(err, requester) {
            if (err) return cb(err);
            mongoose.model('UserSchema').findOne({_id: requesteeID}).exec(function(err, requestee) {
                if (err) return cb(err);
                if (requestee.friendsAccepted(requesterID) === -1 &&
                    requestee.friendsRequested(requesterID) === -1 &&
                    requestee.friendsPending(requesterID) === -1 &&
                    requestee.friendsRejected(requesterID) === -1) {
                    requestee.friendsPending.push(requesterID);
                    requester.friendsRequested.push(requesterID);
                    requestee.save();
                    requester.save();
                    cb(null, true);
                } else {
                    cb(null, false);
                };
            });
        });
    };
    
    UserSchema.statics.requesteeDecidedOnFriendship = function(requesterID, requesteeID, allowed, cb) {
        mongoose.model('UserSchema').findOne({_id: requesterID}).exec(function(err, requester) {
            if (err) return cb(err);
            mongoose.model('UserSchema').findOne({_id: requesteeID}).exec(function(err, requestee) {
                if (err) return cb(err);
                if ((requestee.friendsAccepted(requesterID) === -1 &&
                    requestee.friendsRequested(requesterID) === -1 &&
                    requestee.friendsPending(requesterID) > -1 &&
                    requestee.friendsRejected(requesterID) === -1) &&
                    requester.friendsRequested(requesteeID) > -1) {
                    requestee.friendsPending.forEach(function(uid, idx) {
                        if (uid === requesterID) {
                            requestee.friendsPending.splice(idx, 1);
                            return;
                        };
                    });
                    requester.friendsRequested.forEach(function(uid, idx) {
                        if (uid === requesteeID) {
                            requester.friendsRequested.splice(idx, 1);
                            return;
                        };
                    });
                    if (allowed) {
                        requestee.friendsAccepted.push(requesterID);
                        requester.friendsAccepted.push(requesteeID);
                    } else {
                        requestee.friendsRejected.push(requesterID);
                        requester.friendsRejected.push(requesteeID);
                    }
                    requestee.save();
                    requester.save();
                };
                cb(null);
            });
        });
    }
    
    
    module.exports = mongoose.model('User', UserSchema);
    

    所以发生了一些事情:

    • 尚未测试
    • 它不干燥
    • 没有额外的友谊模式会受到限制

    使用友谊模式,您可以定义拒绝的级别(例如“此时不”等),您可以更好地清除细节并针对友谊的变化行为进行精细控制。从上面可以看出,一旦你被拒绝了,那是相当宿命论的,因为它决定了你们永远不会成为朋友!因此,为了获得更多这种类型的行为,我肯定会使用 Friendship Schema,它的静态和方法都被清除了,用户也应该这样做。

    【讨论】:

      猜你喜欢
      • 2018-10-26
      • 2014-07-27
      • 2021-05-11
      • 1970-01-01
      • 2020-08-01
      • 2016-07-27
      • 2020-11-09
      • 1970-01-01
      • 2015-10-23
      相关资源
      最近更新 更多