修改稿回答
讓我們假設你的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