【问题标题】:Sequelize updateAttributes doesnt work in socket.on( 'disconnet' )Sequelize updateAttributes 在 socket.on('disconnect') 中不起作用
【发布时间】:2014-06-21 07:27:38
【问题描述】:

我想在客户端与套接字断开连接时更新时间。但是,下面的代码从“find({where: {room_id: roomId}})”行中给了我“没有方法 'indexOf'”。有人知道为什么吗?谢谢!

var roomId;
roomId = socket.on('updateStartTime', function(roomId) {
    //some code
    return roomId
});

socket.on('disconnect', function() {
    var date = new Date();

    Room.find({
        where: {
            room_id: roomId
        }
    }).complete(function(err, room) {
        if (err) console.log(err);

        room.updateAttributes({
            end_time: date
        }).success(function(room) {
            console.log("end_time: " + room.end_time);
        });
    });

    socket.broadcast.emit('updateChat', 'SERVER', socket.username + ' has disconnected...');
});

同时,它在从客户端从 socket.emit 触发事件时起作用。

     roomId = socket.on('updateStartTime', function(roomId) {
    var date = new Date();
    Room.find({
        where: {
            room_id: roomId
        }
    }).complete(function(err, room) {
        if (err) console.log(err);
        room.updateAttributes({
            start_time: date
        }).success(function(st) {})
        return roomId;
    });
});

【问题讨论】:

  • 老兄,您误解了事件驱动模型的工作原理。当所有客户端从房间断开连接时,您是否尝试记录?
  • @yaoxing 你好,现在聊天只有一对一。所以我想记录唯一的客户何时与房间断开连接。我是怎么误解事件驱动模型的?

标签: mysql node.js express socket.io sequelize.js


【解决方案1】:

基本上事件驱动模型是当某些事件发生时,您会遇到某个闭包(如果您不知道什么是闭包或它是如何工作的,请查看this thread)。所以你的代码:

roomId = socket.on('updateStartTime', function (roomId) {
    // this is where the closure starts
    return roomId;
    // closure ends here
}

您似乎正试图从闭包外部获取 roomId。但这行不通。您的代码中的错误是:
尽管您希望将其分配给全局 roomId,但“返回 roomId”无处可去。想想看,在事件驱动模型中,你永远不知道这个函数(roomId)什么时候会被执行。因此,当您将 socket.on 结果分配给全局 roomId 时,如果它尚未执行,它如何给您 roomId?由于nodejs的非阻塞模型,它不会阻塞在那里等待结果。实际上,如果您查看 socket.on 的文档,它会立即返回自己,这是一个“套接字”。这就是你得到错误的原因。

代码的第二次和平有效,因为它在闭包内。 roomId 指的是本地的 roomId,它是一个期望值。这段代码仍然不能满足您的需要,因为当有人断开连接时它不会执行。您可以尝试以下方法:

socket.on('updateStartTime', function (roomId) {
    socket.on('disconnect', function() {
        // your 'Room' operation here.
        socket.broadcast.emit('updateChat', 'SERVER', socket.username + ' has disconnected...');
    });
});

请记住,在事件驱动模型中,它不是按顺序执行的。任何事情都可能随时发生。你需要在正确的地方做正确的事。

【讨论】:

  • 感谢您的回复。这也可以解释为什么当我尝试在 socket.on(disconnect) 中使用 JSON.stringify 打印 roomId 时出现 TypeError: Converting circular structure to JSON。
  • 我想我需要想出一个更好的方法来获取 roomId。我需要为此打开一个新线程。顺便说一句,Room 是一个数据库模型,它将在我的数据库中存储聊天信息。 roomId 是主键 auto_increment。
  • 另外,我在客户端有一个 socket.emit('updateStartTime', roomId) 会在聊天开始时触发。那么这是否意味着我们可以知道 roomId 何时通过 socket.on() 传递到服务器端?
  • 您可以将 socket.on("disconnect") 放入 socket.on('updateStartTime') 中,正如我在修改后的答案中所示
  • 谢谢你的方法有效!感谢您的帮助!我想我现在更好地理解事件驱动和关闭:)
猜你喜欢
  • 2017-05-20
  • 2017-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多