Node.js - Socket.io - Express 3

4

我对Node.js和Express不太熟悉 :( 我在访问其他模块中的socket.io对象时遇到了问题。我已经创建了一个全局变量来保存socket对象,但是当用户关闭连接时,该连接将不再可用。从技术上讲,我想这个连接仍然存在,但为了资源原因,我删除了它。

请注意,每当建立连接时,我们将该socket分配给全局变量,全局变量可以被所有其他模块访问。

// App.js
var io = require('socket.io').listen(server); 
var sessionsConnections = {};

io.sockets.on('connection', function (socket) 
{
     global.socket = socket;
     sessionsConnections[socket.id] = socket;
     .....
}

socket.on("disconnect", function() 
{
    delete sessionsConnections[socket.id];
});

// Match.js
     global.socket.emit('lobby:createMatch', data);

如果上一次分配给全局的连接关闭了,Match.js 将会出现问题。此时,Match.js 是唯一需要那个 socket.io 引用的模块。Match.js 有许多导出项,用于处理事件、发出更改和渲染视图。
是否有任何建议来处理这个问题?是否可以实例化一个初始套接字连接,以在 App.js 中存在作为全局引用的目的?

你是在尝试制作只处理一个连接的东西吗? 在发出信号之前,你测试了global.socket的值吗? 你得到了什么错误? - Arnaud Rinquin
用户一直在创建和连接比赛。问题是这种设计虽然可行,但并不完美。当我测试并连接一个套接字,将其分配给全局变量,断开并关闭套接字,然后尝试在全局套接字上发出信号时,它会挂起,最终会出现找不到套接字或其他错误的错误提示。 - Charles Peterson
好的,我觉得你没有明白 socket 不是唯一的,而是每个用户都不同。Lortabac 的答案会帮助你的 ;) - Arnaud Rinquin
不错的格式化问题的方式!这正是我的问题所在! - neophyte
2个回答

4
io.sockets.on('connection', function(socket) {...})中的socket变量对于每个连接都是不同的。
由于在您的代码中,global.socket始终引用相对于最后连接的客户端的套接字,如果此客户端断开连接,则此套接字将会失效。
无论如何,我没有看到使用全局变量的任何理由。如果您需要向特定客户端发送消息,可以在连接回调函数中使用socket变量。
io.sockets.on('connection', function (socket) 
{
  socket.emit('foo', 'bar');
}

如果您需要访问另一个模块中的套接字,可以导出sessionsConnections对象,并通过其ID访问所需的套接字:
//In app.js
exports.connections = sessionsConnections;

//In match.js
var app = require('./app.js');
app.connections[clientId].emit('foo', 'bar');

当然,你需要在某个地方跟踪id。

这就是为什么我问Charles是否只有一个客户端可以连接。我认为他没有理解套接字在每个连接中是唯一的事实。好答案 ;) - Arnaud Rinquin
我知道每个套接字都是独一无二的,每个连接都有一个。我试图做的是警告其他连接的用户,用户A已经断开连接。如果用户A被绑定到全局(因为他是最后一个连接的),显然发射不起作用。如果客户端ID没有被删除,Lortabac的解决方案将起作用。请记住,用户已经断开连接,他们的套接字连接不再可用于发射。我可以从sessionsConnections对象中访问另一个客户端ID。 - Charles Peterson

0
你可以尝试使用express.io

http://express-io.org/

npm install express.io

它的工作方式与express相同,只是它内置了socket.io集成。它还具有基本路由功能,因此处理问题会更容易一些。

请查看这个简单的示例:

app = require('express.io')()
app.http().io()

app.io.route('some-event', function(req) {
    req.io.broadcast('announce', 'someone triggered some-event')
})

app.listen(7076)

你也可以使用对象进行路由,这使得它更像传统的控制器:

app = require('express.io')()
app.http().io()

app.io.route('posts', {
    create: function(req) {
        // create a post
    },
    remove: function(req) {
        // remove a post
    }
})

app.listen(7076)

希望这有帮助!

哦耶,会话自动工作!只需在express中按照正常设置它们,它们也将与io请求连接起来。 - Brad C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接