套接字的客户端范围在'disconnect'事件(服务器端)上会发生什么

时间:2015-03-06 17:33:44

标签: javascript node.js mongoose socket.io

那么在'disconnect'事件中socket的客户端作用域会发生什么?

我正在尝试避免我的node.js + mongoose + socket.io app中的恶劣赛车条件和逻辑缺陷。

范围是什么意思:

io.on('connection', function (client) { 
///CLIENT SCOPE///
//define private vars, store and operate client's session info//
//recieving and sending client's socket signals//
}

一些背景: 比方说,例如,我通过查找room并将user写入此room来实现一些操作数据库的函数。

但是,在room(要写入)找到但用户尚未写入的那一刻,他断开连接。在断开连接事件时,我必须把他拉出他在db的最后一个房间,但是我不能,它现在还没有保存在数据库中。 我看到的唯一方法是在bool事件上指定一个'disconnect'值,我可以在将该人员保存到room之前检查该事件,并且在true don'的情况下拯救他。

我感到困惑的是 - 这个bool能否在断开连接事件中存活,因为它保存在客户端的范围内。

范围会发生什么?在断开连接时它完全消失了吗?或者只有在完成依赖于此范围的所有内容时才会消失?

我正在使用'forceNew': true强制socket.connect();如果出现问题(假设)并且socket error在没有用户真正离开网站的情况下立即执行套接字。
如果用户通过这个“旧”套接字重新连接,他是否在服务器上恢复了他的作用域,或者这个套接字的先前作用域在断开连接时已被清除,或者在'connection'事件重新连接时被清除?

1 个答案:

答案 0 :(得分:1)

只要运行使用该闭包的代码,client闭包就会保持活动状态,因此您通常不必担心该问题。闭包本质上是Javascript中的一个对象,当没有活动代码引用闭包内的任何内容时,它只会被垃圾收集。

对于在写入数据库时​​断开套接字的并发问题,您应该认识到这是一个需要注意的问题。您需要做什么,具体取决于数据库的行为方式。由于node.js运行单线程,因此在处理任何断开连接事件之前,写入数据库的node.js代码将运行完成。这并不意味着数据库写入将在断开连接事件开始处理之前完成,但它确实意味着它已经被发送到数据库。因此,如果您的数据库按照接收它们的顺序处理多个请求,那么它可能只是做正确的事情,您将不会有任何额外的代码需要担心。

如果您的数据库在写入完成之前实际上可以处理删除(这似乎不太可能),那么您必须为此编写一些保护。最简单的概念是在给定用户的所有数据库操作上实现数据库队列。我可能会在其上创建一个带有通用DB方法的对象来实现此队列,并在每个client闭包中创建一个单独的对象,这样它们就是给定用户的本地对象。当数据库操作正在进行时,此对象将具有一个标志,指示操作正在进行中。如果在设置此标志时调用了另一个数据库操作,则第二个操作将进入队列而不是直接发送到数据库。每次数据库操作完成时,它都会检查队列以查看是否有下一个操作正在等待运行。如果是这样,它会运行它。

仅供参考,我有一个简单的node.js应用程序(在带有温度传感器的Raspberry Pi上运行)记录温度数据,并且每隔一段时间它就会使用异步写入将数据写入磁盘。因为新的温度数据可能会在我处于异步写入数据的过程中到达,所以我遇到了类似的问题。我抽象了对象中数据的所有操作,实现了一个标志,指示我是否正在编写数据,如果有任何方法调用到达以修改数据,那么这些操作会进入队列并进行处理只有当写完了。​​


关于您的上一个问题,client关闭中的io.on('connection', ...)范围仅与该特定connection事件相关联。如果你得到另一个connection事件并因此触发该代码再次运行,那将创建一个与前一个无关的新的单独闭包,即使client对象是相同的。通常情况下,这很好,因为此函数中的代码只会为新连接重新设置。