【发布时间】:2014-09-03 03:30:14
【问题描述】:
我读了很多关于 Express / SocketIO 的文章,这太疯狂了,除了直接从 app.js 传输的“Hello”之外,你很少得到其他示例。问题是它在现实世界中并不像那样工作......我实际上对一个似乎与网络给我的东西相去甚远的逻辑问题感到绝望,这就是我想指出这一点的原因,我敢肯定询问将是解决方案! :)
我正在重构我的应用程序(因为有很多错误,例如使用全局范围放置库等);假设我有一个基于 SocketIO 和 NodeJS 的庞大系统。 app.js 中有一个加载器,用于启动套接字系统。
当有人加入应用程序时,它需要() 另一个模块:它初始化许多动态加载的 socket.on() 并转到文件夹中的一些 /*_socket.js 文件。这些模块中的每个函数都代表一个套接字侦听器,然后从前端调用它会更容易,可能如下所示:
// Will call `user_socket.js` and method `try_to_signin(some params)`
Queries.emit_socket('user.try_to_signin', {some params});
系统本身运行良好。但是有一个问题:将加载所有那些了解前端已发送内容的文件的模块还传输与 req/res 链接的库(会话、cookie、其他......)并且必须这样做,因为调用的方法是应用程序的核心,并且经常需要这些库。
在前面的示例中,我们显然需要检查用户是否尚未登录。
// The *_socket.js file looks like this :
var $h = require(__ROOT__ + '/api/helpers');
module.exports = function($s, $w) {
var user_process = require(__ROOT__ + '/api/processes/user_process')($s, $w);
return {
my_method_called: function(reference, params, callback) {
// Stuff using $s, $w, etc.
}
}
// And it's called this way :
// $s = services (a big object)
// $w = workers (a big object depending on $s)
// They are linked with the req/res from the page when they are instantiated
controller_instance = require('../sockets/'+ controller_name +'_socket')($s, $w);
// After some processes ...
socket_io.on(socket_listener, function (datas, callback) {
// Will call the correct function, etc.
$w.queries.handle_socket($w, controller_name, method_name, datas);
});
好消息:基本上,它有效。
坏消息:每次我刷新页面时,监听器都会加倍,因为它们处于一个称为页面加载的循环中。
下面,这应该是一行:
所以我应该把所有的 socket.on('connection'...) 东西放在页面加载之外,这意味着当服务器启动时......是的,但我还需要 req/res 数据才能加载库,我只有在页面加载时才能得到!
这是一个编程逻辑问题,我知道我做错了,但我现在不知道该去哪里,我得到了这个“基本上”可以工作的大系统,但我做的方式有点矛盾,我可以'不知道如何解决这个问题......我被困了几个小时。
我怎样才能根据 socket.on() 调用中的 req/res 来重构以获取当前库的可能性? 有窍门吗?我应该考虑完全改变我的做法吗?
另外,还有其他方法可以做我想做的事吗?
谢谢大家!
注意:如果我没有很好地解释或者如果您想要更多代码,请告诉我 :)
编辑 - 解决方案: 如上所示,我们可以使用 sockets.once();而不是 sockets.on(),或者还有不那么干净的 sockets.removeAllListeners() 解决方案。
【问题讨论】:
标签: javascript node.js sockets express socket.io