























@@ -14,6 +14,7 @@ const TWITCH_CHAT_AUTH_INTENTS = ["chat"];
1414export class TwitchClientManager {
1515private clients = new Map<string, ChatClient>();
1616private messageHandlers = new Map<string, (message: TwitchChatMessage) => void>();
17+private messageHandlerTokens = new Map<string, symbol>();
17181819constructor(private logger: ChannelLogSink) {}
1920@@ -204,9 +205,16 @@ export class TwitchClientManager {
204205handler: (message: TwitchChatMessage) => void,
205206): () => void {
206207const key = this.getAccountKey(account);
208+const token = Symbol(key);
207209this.messageHandlers.set(key, handler);
210+this.messageHandlerTokens.set(key, token);
208211return () => {
209-this.messageHandlers.delete(key);
212+// Only remove the exact registration this cleanup closure owns. A later
213+// onMessage() may reuse the same callback function for the same account.
214+if (this.messageHandlerTokens.get(key) === token) {
215+this.messageHandlers.delete(key);
216+this.messageHandlerTokens.delete(key);
217+}
210218};
211219}
212220@@ -221,6 +229,7 @@ export class TwitchClientManager {
221229client.quit();
222230this.clients.delete(key);
223231this.messageHandlers.delete(key);
232+this.messageHandlerTokens.delete(key);
224233this.logger.info(`Disconnected ${key}`);
225234}
226235}
@@ -232,6 +241,7 @@ export class TwitchClientManager {
232241this.clients.forEach((client) => client.quit());
233242this.clients.clear();
234243this.messageHandlers.clear();
244+this.messageHandlerTokens.clear();
235245this.logger.info(" Disconnected all clients");
236246}
237247이 콘텐츠는 인셔셔RSS(RSS 리더)가 자동으로 집계한 것으로 읽기 참고용입니다. 원문 출처 — 저작권은 원저작자에게 있습니다.