@@ -2,6 +2,8 @@ import type { Message, MessageConnect, MessageSend, RuntimeMessageSender, TMessa
22import { uuidv4 } from "@App/pkg/utils/uuid" ;
33import EventEmitter from "eventemitter3" ;
44
5+ const listenerMgr = new EventEmitter < string , any > ( ) ; // 单一管理器
6+
57// 通过 window.postMessage/onmessage 实现通信
68
79export interface PostMessage {
@@ -121,19 +123,41 @@ export class WindowMessage implements Message {
121123}
122124
123125export class WindowMessageConnect implements MessageConnect {
126+ private readonly listenerId = `${ uuidv4 ( ) } ` ; // 使用 uuidv4 确保唯一
127+ private target : PostMessage | null ;
128+ private isSelfDisconnected = false ;
129+
124130 constructor (
125131 private messageId : string ,
126- private EE : EventEmitter < string , any > ,
127- private target : PostMessage
132+ EE : EventEmitter < string , any > ,
133+ target : PostMessage
128134 ) {
129- this . onDisconnect ( ( ) => {
130- // 移除所有监听
131- this . EE . removeAllListeners ( "connectMessage:" + this . messageId ) ;
132- this . EE . removeAllListeners ( "disconnect:" + this . messageId ) ;
133- } ) ;
135+ this . target = target ; // 强引用
136+ const handler = ( msg : TMessage ) => {
137+ listenerMgr . emit ( `onMessage:${ this . listenerId } ` , msg ) ;
138+ } ;
139+ const cleanup = ( ) => {
140+ if ( this . target ) {
141+ this . target = null ;
142+ listenerMgr . removeAllListeners ( `cleanup:${ this . listenerId } ` ) ;
143+ EE . removeAllListeners ( "connectMessage:" + this . messageId ) ; // 模拟 con.onMessage.removeListener
144+ EE . removeAllListeners ( "disconnect:" + this . messageId ) ; // 模拟 con.onDisconnect.removeListener
145+ listenerMgr . emit ( `onDisconnect:${ this . listenerId } ` , this . isSelfDisconnected ) ;
146+ listenerMgr . removeAllListeners ( `onDisconnect:${ this . listenerId } ` ) ;
147+ listenerMgr . removeAllListeners ( `onMessage:${ this . listenerId } ` ) ;
148+ }
149+ } ;
150+ EE . addListener ( `connectMessage:${ this . messageId } ` , handler ) ; // 模拟 con.onMessage.addListener
151+ EE . addListener ( `disconnect:${ this . messageId } ` , cleanup ) ; // 模拟 con.onDisconnect.addListener
152+ listenerMgr . once ( `cleanup:${ this . listenerId } ` , cleanup ) ;
134153 }
135154
136155 sendMessage ( data : TMessage ) {
156+ if ( ! this . target ) {
157+ console . error ( "Attempted to sendMessage on a disconnected Target." ) ;
158+ // 無法 sendMessage 不应该屏蔽错误
159+ throw new Error ( "Attempted to sendMessage on a disconnected Target." ) ;
160+ }
137161 const body : WindowMessageBody < TMessage > = {
138162 messageId : this . messageId ,
139163 type : "connectMessage" ,
@@ -143,20 +167,38 @@ export class WindowMessageConnect implements MessageConnect {
143167 }
144168
145169 onMessage ( callback : ( data : TMessage ) => void ) {
146- this . EE . addListener ( `connectMessage:${ this . messageId } ` , callback ) ;
170+ if ( ! this . target ) {
171+ console . error ( "onMessage Invalid Target" ) ;
172+ // 無法監聽的話不应该屏蔽错误
173+ throw new Error ( "onMessage Invalid Target" ) ;
174+ }
175+ listenerMgr . addListener ( `onMessage:${ this . listenerId } ` , callback ) ;
147176 }
148177
149178 disconnect ( ) {
179+ if ( ! this . target ) {
180+ console . warn ( "Attempted to disconnect on a disconnected Target." ) ;
181+ // 重复 disconnect() 不应该屏蔽错误
182+ throw new Error ( "Attempted to disconnect on a disconnected Target." ) ;
183+ }
184+ this . isSelfDisconnected = true ;
150185 const body : WindowMessageBody < TMessage > = {
151186 messageId : this . messageId ,
152187 type : "disconnect" ,
153188 data : null ,
154189 } ;
155190 this . target . postMessage ( body ) ;
191+ // Note: .disconnect() will NOT automatically trigger the 'cleanup' listener
192+ listenerMgr . emit ( `cleanup:${ this . listenerId } ` ) ;
156193 }
157194
158- onDisconnect ( callback : ( ) => void ) {
159- this . EE . addListener ( `disconnect:${ this . messageId } ` , callback ) ;
195+ onDisconnect ( callback : ( isSelfDisconnected : boolean ) => void ) {
196+ if ( ! this . target ) {
197+ console . error ( "onDisconnect Invalid Target" ) ;
198+ // 無法監聽的話不应该屏蔽错误
199+ throw new Error ( "onDisconnect Invalid Target" ) ;
200+ }
201+ listenerMgr . once ( `onDisconnect:${ this . listenerId } ` , callback ) ;
160202 }
161203}
162204
0 commit comments