【问题标题】:Node.js - Socket.io - Express 3Node.js - Socket.io - Express 3
【发布时间】:2012-11-24 06:05:33
【问题描述】:

我是 Node.js 和 Express 的菜鸟 :( 我在访问其他模块中的 socket.io 对象时遇到问题。我已经创建了一个全局变量来保存一个套接字对象,但是只要该用户关闭连接,连接不再可用。从技术上讲,我猜连接仍然存在,但出于资源原因我将其删除。

请注意,每次建立连接时,我们都会将该套接字分配给所有其他模块都可以访问的全局变量。

// 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 的值吗?你得到什么错误?
  • 用户一直在创建和连接匹配。问题是这种设计有效,但不是完全证明。当我测试并连接一个套接字时,将其分配给全局,断开并终止套接字,然后尝试在 global.socket 上发射它挂起,最终我得到一个错误,说找不到套接字或其他东西。
  • 好吧,我想你没有明白socket 不是唯一的,而是对每个用户都不同的事实。 lortabac 的答案会帮助你 ;)
  • 格式化问题的好方法!这正是我的问题所在!

标签: node.js sockets express socket.io


【解决方案1】:

你可以试试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 请求中。
【解决方案2】:

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。

【讨论】:

  • 这就是为什么我问查尔斯是否只有一个客户端可以连接。我认为他不理解每个连接唯一的套接字这一事实。好答案;)
  • 我确实知道每个连接的每个套接字都是唯一的。我试图做的是提醒其他连接的用户 userA 已断开连接。如果 userA 绑定到全局(因为他是最后一个连接的),显然发射将不起作用。如果未删除 clientID,Lortabac 的解决方案将起作用。请记住,用户已断开连接,并且他们的套接字连接不再可用于发出。我可以从 sessionConnections 对象访问另一个 clientID。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-01
  • 2011-04-19
  • 2012-04-27
  • 2014-10-20
  • 1970-01-01
相关资源
最近更新 更多