サブスクリプションモデルの実装方法
デフォルトでは、イベントは、相手側に登録されたイベントハンドラーがない場合でも、ワイヤーを介して送信されます。
注記
キャッチオールリスナーを使用して、これらの欠落しているイベントハンドラーをキャッチできます。
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]);
}
});
これはよりクリーンです(たとえば、重複したサブスクリプションを処理する必要はありません)。ただし、古いプラットフォームをターゲットにする必要がある場合は、ポリフィルが必要です。
接続状態の復元
"connect"ハンドラー内
socket.on("connect", () => {
if (subscriptions.length && !socket.recovered) {
socket.emit("subscribe", subscriptions);
}
});
!socket.recovered
条件は、接続状態の復元機能に関連しています。
接続状態が正常に復元された場合、サブスクリプション(サーバー側のルーム)は自動的に復元されます。