feat: Implement proactive access token refreshing within the session and reactive token renewal for socket authentication errors.
This commit is contained in:
@@ -22,11 +22,15 @@ class SocketService {
|
||||
private statusHandlers: Set<StatusHandler> = new Set();
|
||||
private readHandlers: Set<ReadHandler> = new Set();
|
||||
private connectionHandlers: Set<(connected: boolean) => void> = new Set();
|
||||
private authErrorHandlers: Set<() => void> = new Set();
|
||||
private isConnecting = false;
|
||||
private currentToken: string | null = null;
|
||||
|
||||
connect(token: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Already connected
|
||||
this.currentToken = token;
|
||||
|
||||
// Already connected with same token
|
||||
if (this.socket?.connected) {
|
||||
resolve();
|
||||
return;
|
||||
@@ -84,6 +88,12 @@ class SocketService {
|
||||
console.log('Socket disconnected:', reason);
|
||||
this.isConnecting = false;
|
||||
this.notifyConnectionHandlers(false);
|
||||
|
||||
// "io server disconnect" means the server rejected us (likely auth failure)
|
||||
if (reason === 'io server disconnect') {
|
||||
console.warn('Socket: Server disconnected us (likely token expired). Requesting token refresh...');
|
||||
this.authErrorHandlers.forEach((handler) => handler());
|
||||
}
|
||||
});
|
||||
|
||||
this.socket.on('connect_error', (error) => {
|
||||
@@ -118,11 +128,26 @@ class SocketService {
|
||||
});
|
||||
}
|
||||
|
||||
// Reconnect with a fresh token (used when the previous token expired)
|
||||
reconnectWithToken(token: string): void {
|
||||
this.currentToken = token;
|
||||
if (this.socket) {
|
||||
// Update the auth token for reconnection
|
||||
this.socket.auth = { token };
|
||||
this.socket.connect();
|
||||
} else {
|
||||
this.connect(token).catch((err) => {
|
||||
console.error('Socket reconnect with new token failed:', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
disconnect(): void {
|
||||
if (this.socket) {
|
||||
this.socket.disconnect();
|
||||
this.socket = null;
|
||||
}
|
||||
this.currentToken = null;
|
||||
}
|
||||
|
||||
isConnected(): boolean {
|
||||
@@ -225,6 +250,11 @@ class SocketService {
|
||||
return () => this.connectionHandlers.delete(handler);
|
||||
}
|
||||
|
||||
onAuthError(handler: () => void): () => void {
|
||||
this.authErrorHandlers.add(handler);
|
||||
return () => this.authErrorHandlers.delete(handler);
|
||||
}
|
||||
|
||||
private notifyConnectionHandlers(connected: boolean): void {
|
||||
this.connectionHandlers.forEach((handler) => handler(connected));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user