@@ -24,13 +24,13 @@ const TICK_INTERVAL = 50;
24
24
const REQUEST_INTERVAL = 50 ;
25
25
26
26
export class Client extends Emitter < ClientEvents > {
27
- public socket ! : Socket ;
28
- public framer ! : Framer ;
27
+ public socket ! : Socket | null ;
28
+ public framer ! : Framer | null ;
29
29
public options : ClientOptions ;
30
30
private tickTimer ?: NodeJS . Timeout ;
31
31
private connectionTimeout ?: NodeJS . Timeout ;
32
32
private requestInterval ?: NodeJS . Timeout ;
33
- public serverAddress ! : Address ;
33
+ public serverAddress ! : Address | null ;
34
34
35
35
public status = Status . Disconnected ;
36
36
@@ -45,12 +45,12 @@ export class Client extends Emitter<ClientEvents> {
45
45
this . socket = createSocket ( "udp4" ) ;
46
46
this . framer = new Framer ( this ) ;
47
47
48
- this . remove ( "tick" , ( ) => this . framer . tick ( ) ) ;
49
- this . on ( "tick" , ( ) => this . framer . tick ( ) ) ;
48
+ this . remove ( "tick" , ( ) => this . framer ? .tick ( ) ) ;
49
+ this . on ( "tick" , ( ) => this . framer ? .tick ( ) ) ;
50
50
51
- this . socket . removeAllListeners ( "message" ) ;
51
+ this . socket . removeAllListeners ( ) ;
52
52
this . socket . on ( "message" , ( payload , rinfo ) => {
53
- this . framer . incommingMessage ( payload , rinfo ) ;
53
+ this . framer ? .incommingMessage ( payload , rinfo ) ;
54
54
} ) ;
55
55
56
56
this . socket . on ( "error" , ( err ) => {
@@ -171,6 +171,10 @@ export class Client extends Emitter<ClientEvents> {
171
171
172
172
public sendFrame ( frame : Frame , priority : Priority ) : void {
173
173
try {
174
+ if ( ! this . framer ) {
175
+ Logger . error ( "[Client] Cannot send frame: framer is null" ) ;
176
+ return ;
177
+ }
174
178
this . framer . sendFrame ( frame , priority ) ;
175
179
} catch ( error ) {
176
180
Logger . error ( "[Client] Failed to send frame" , error ) ;
@@ -190,6 +194,11 @@ export class Client extends Emitter<ClientEvents> {
190
194
return ;
191
195
}
192
196
197
+ if ( ! this . socket ) {
198
+ Logger . error ( "[Client] Cannot send packet: socket is null" ) ;
199
+ return ;
200
+ }
201
+
193
202
Logger . debug (
194
203
`[Client] Sending packet ${ buffer [ 0 ] } , ${ buffer . length } bytes to ${ this . options . address } :${ this . options . port } ` ,
195
204
) ;
@@ -212,6 +221,62 @@ export class Client extends Emitter<ClientEvents> {
212
221
}
213
222
}
214
223
224
+ private cleanupSocket ( ) {
225
+ if ( ! this . socket ) return ;
226
+ try {
227
+ this . socket . removeAllListeners ( ) ;
228
+ Logger . cleanup ( ) ;
229
+ if ( this . status === Status . Connected ) {
230
+ const disconnect = new DisconnectionNotification ( ) ;
231
+ this . socket . send (
232
+ disconnect . serialize ( ) ,
233
+ 0 ,
234
+ disconnect . serialize ( ) . length ,
235
+ this . options . port ,
236
+ this . options . address ,
237
+ ) ;
238
+ }
239
+
240
+ const stateSymbol = Symbol . for ( "state symbol" ) ;
241
+ const socketWithState = this . socket as unknown as {
242
+ [ key : symbol ] : { handle : { close : ( ) => void } | null } ;
243
+ } ;
244
+ const state = socketWithState [ stateSymbol ] ;
245
+ if ( state ?. handle ) {
246
+ state . handle . close ( ) ;
247
+ state . handle = null ;
248
+ }
249
+
250
+ this . socket . close ( ( ) => {
251
+ console . log ( "socket closed" ) ;
252
+ this . socket ?. removeAllListeners ( ) ;
253
+ } ) ;
254
+
255
+ // (this.socket as { _handle?: unknown })._handle = undefined;
256
+ } catch ( err ) {
257
+ Logger . error ( "[Client] Error during socket cleanup" , err as Error ) ;
258
+ try {
259
+ const stateSymbol = Symbol . for ( "state symbol" ) ;
260
+ const socketWithState = this . socket as unknown as {
261
+ [ key : symbol ] : { handle : { close : ( ) => void } | null } ;
262
+ } ;
263
+ const state = socketWithState [ stateSymbol ] ;
264
+ if ( state ?. handle ) {
265
+ state . handle . close ( ) ;
266
+ state . handle = null ;
267
+ }
268
+ } catch ( _ ) { }
269
+ this . socket = null ;
270
+ }
271
+ }
272
+
273
+ private cleanupFramer ( ) {
274
+ if ( ! this . framer ) return ;
275
+ ( this . framer as { _events ?: unknown } ) . _events = undefined ;
276
+ ( this . framer as { _eventsCount ?: unknown } ) . _eventsCount = undefined ;
277
+ this . framer = null ;
278
+ }
279
+
215
280
public cleanup ( ) : void {
216
281
if ( this . status === Status . Disconnected ) return ;
217
282
@@ -237,56 +302,13 @@ export class Client extends Emitter<ClientEvents> {
237
302
this . removeAll ( ) ;
238
303
this . removeAllAfter ( ) ;
239
304
this . removeAllBefore ( ) ;
240
-
241
- if ( this . socket ) {
242
- try {
243
- this . socket . removeAllListeners ( ) ;
244
- Logger . cleanup ( ) ;
245
- if ( wasConnected ) {
246
- const disconnect = new DisconnectionNotification ( ) ;
247
- this . socket . send (
248
- disconnect . serialize ( ) ,
249
- 0 ,
250
- disconnect . serialize ( ) . length ,
251
- this . options . port ,
252
- this . options . address
253
- ) ;
254
- }
255
-
256
- const state = ( this . socket as any ) [ Symbol . for ( 'state symbol' ) ] ;
257
- if ( state ?. handle ) {
258
- state . handle . close ( ) ;
259
- state . handle = null ;
260
- }
261
-
262
- this . socket . close ( ( ) => {
263
- console . log ( "socket closed" ) ;
264
- this . socket . removeAllListeners ( ) ;
265
- } ) ;
266
-
267
- delete ( this . socket as any ) . _handle ;
268
- } catch ( err ) {
269
- Logger . error ( "[Client] Error during socket cleanup" , err as Error ) ;
270
- try {
271
- const state = ( this . socket as any ) [ Symbol . for ( 'state symbol' ) ] ;
272
- if ( state ?. handle ) {
273
- state . handle . close ( ) ;
274
- state . handle = null ;
275
- }
276
- } catch ( _ ) { }
277
- this . socket = undefined as any ;
278
- }
279
- }
280
305
281
- if ( this . framer ) {
282
- delete ( this . framer as any ) . _events ;
283
- delete ( this . framer as any ) . _eventsCount ;
284
- this . framer = undefined as any ;
285
- }
306
+ this . cleanupSocket ( ) ;
307
+ this . cleanupFramer ( ) ;
286
308
287
- this . serverAddress = undefined as any ;
288
- delete ( this as any ) . _events ;
289
- delete ( this as any ) . _eventsCount ;
309
+ this . serverAddress = null ;
310
+ ( this as { _events ?: unknown } ) . _events = undefined ;
311
+ ( this as { _eventsCount ?: unknown } ) . _eventsCount = undefined ;
290
312
this . status = Status . Disconnected ;
291
313
292
314
Logger . debug ( "[Client] Cleanup complete" ) ;
0 commit comments