如何實作訂閱模型
預設情況下,即使另一端沒有註冊事件處理常式,事件也會透過網路傳送。
注意事項
您可以使用萬用監聽器來捕捉那些遺失的事件處理常式
socket.onAny((event) => {
if (socket.listeners(event).length === 0) {
console.log(`missing handler for event ${event}`);
}
});
參考:onAny()
方法
若要僅接收特定事件清單(例如,如果您的應用程式的一部分只需要少數事件),您可以實作訂閱模型
用戶端
const subscriptions = [];
function subscribe(topic) {
subscriptions.push(topic);
if (socket.connected) {
socket.emit("subscribe", [topic]);
}
}
function unsubscribe(topic) {
const i = subscriptions.indexOf(topic);
if (i !== -1) {
subscriptions.splice(i, 1);
if (socket.connected) {
socket.emit("unsubscribe", topic);
}
}
}
// restore the subscriptions upon reconnection
socket.on("connect", () => {
if (subscriptions.length && !socket.recovered) {
socket.emit("subscribe", subscriptions);
}
});
subscribe("foo");
伺服器
io.on("connection", (socket) => {
socket.on("subscribe", (topics) => {
socket.join(topics);
});
socket.on("unsubscribe", (topic) => {
socket.leave(topic);
});
// send an event only to clients that have shown interest in the "foo" topic
io.to("foo").emit("foo");
});
其他注意事項
訂閱清單
我們可以在客戶端上使用 ES6 Set 來訂閱
const subscriptions = new Set();
function subscribe(topic) {
subscriptions.add(topic);
if (socket.connected) {
socket.emit("subscribe", [topic]);
}
}
function unsubscribe(topic) {
const deleted = subscriptions.delete(topic);
if (deleted && socket.connected) {
socket.emit("unsubscribe", topic);
}
}
// restore the subscriptions upon reconnection
socket.on("connect", () => {
if (subscriptions.size) {
socket.emit("subscribe", [...subscriptions]);
}
});
這比較簡潔(例如,不需要處理重複訂閱),但如果你需要針對 舊平台,則需要一個 polyfill。
連線狀態復原
在「連線」處理器中
socket.on("connect", () => {
if (subscriptions.length && !socket.recovered) {
socket.emit("subscribe", subscriptions);
}
});
!socket.recovered
條件與 連線狀態復原功能有關。
如果連線狀態復原成功,則訂閱(伺服器端的房間)將自動復原。