修改稿回答
让我们假设你的API端点在config/routes.js
定义是这样的:
...
'get /collect': 'SomeController.collectSubscribe',
'delete /collect': 'SomeController.collectUnsubscribe',
由于每个Cap
实例绑定到一个设备,我们需要为每个订阅一个实例。我们没有使用方法join
/leave
方法,而是跟踪内存中的Cap
实例,并且仅对请求套接字的ID为broadcast
。这是有效的,因为默认情况下,Sails套接字订阅了它们自己的ID。
在api/controllers/SomeController.js
:
// In order for the `Cap` instances to persist after `collectSubscribe` finishes, we store them all in an Object, associated with which socket the were created for.
var caps = {/* req.socket.id: <instance of Cap>, */};
module.exports = {
...
collectSubscribe: function(req, res) {
if (!res.isSocket) return res.badRequest("I need a websocket! Help!");
if (!!caps[req.socket.id]) return res.badRequest("Dude, you are already subscribed.");
caps[req.socket.id] = new Cap();
var c = caps[req.socket.id]; // remember that `c` is a reference to our new `Cap`, not a copy.
var device = c.findDevice(req.param('ip'));
c.open(device, ...);
c.on('data', function(myData) {
sails.sockets.broadcast(req.socket.id, 'message', {host: myData});
});
return res.ok();
},
collectUnsubscribe: function(req, res) {
if (!res.isSocket) return res.badRequest("I need a websocket! Help!");
if (!caps[req.socket.id]) return res.badRequest("I can't unsubscribe you unless you actually subscribe first.");
caps[req.socket.id].removeAllListeners('data');
delete caps[req.socket.id];
return res.ok();
}
}
基本上,它是这样的:当浏览器请求触发collectSubscribe
,新Cap
实例监听提供的IP。当浏览器触发collectUnsubscribe
时,服务器会检索该实例,告诉其停止监听,然后将其删除。
生产注意事项:请注意,Cap
s列表不是数据库持久存储器(因为它存储在内存中而不是数据库)!因此,如果您的服务器关闭并重新启动(由于雷雨天气等),清单将被清除,但考虑到所有websocket连接都将被丢弃,我不认为有任何必要担心这一点。
老回答,不停地为参考
您可以使用sails.sockets.join(req, room)
和sails.sockets.leave(req, room)
管理插座的房间。基本上你有一个叫做“collect”的房间,只有加入该房间的套接字才会收到sails.sockets.broadcast(room, eventName, data)
。
有关如何给用户的信息sails.sockets
here。
在api/controllers/SomeController.js
:
collectSubscribe: function(req, res) {
if (!res.isSocket) return res.badRequest();
sails.sockets.join(req, 'collect');
return res.ok();
},
collectUnsubscribe: function(req, res) {
if (!res.isSocket) return res.badRequest();
sails.sockets.leave(req, 'collect');
return res.ok();
}
最后,我们需要告诉服务器发送广播消息到我们的房间'collect'
。 请注意,这只需要发生一次,因此您可以在config/
目录下的文件中执行此操作。
在这个例子中,我把这个config/sockets.js
module.exports = {
// ...
};
c.on('data', function(myData) {
var eventName = 'message';
var data = {host: myData};
sails.sockets.broadcast('collect', eventName, data);
});
我假设c
在这里访问;如果没有,您可以将其定义为sails.c = ...
以使其可全局访问。
首先,感谢一个真棒的答案!我有一个问题:目前我必须使用从请求'(req.param(“ip”))''得到的参数来初始化'c',并且每个用户需要在他自己的房间中。 OK('data')'根据用户输入发出新数据 – TheUnreal
好的,哇,这是我设想的不同的最终目标!如果你可以用这些具体的细节来编辑你的问题,这将有很大的帮助。另外,我想看看'c'是如何声明的,因为它现在看起来与这个问题更相关。谢谢! – ContinuousLoad
对于混淆感到抱歉,只有在我看到您的答案后才提出来。我相应地更新了我的问题 – TheUnreal