如何实现订阅模型
默认情况下,即使另一端没有注册事件处理程序,事件也会通过网络发送。
注意
您可以使用通配符监听器捕获这些缺失的事件处理程序
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
条件与 连接状态恢复功能 相关。
如果连接状态成功恢复,则订阅(服务器端的房间)将自动恢复。