105 lines
2.6 KiB
JavaScript
105 lines
2.6 KiB
JavaScript
import { io } from 'socket.io-client';
|
|
|
|
|
|
class SocketManager {
|
|
constructor() {
|
|
this.socket = io('', {
|
|
transports: ["websocket"],
|
|
autoConnect: false
|
|
});
|
|
|
|
this.emit = this.emit.bind(this);
|
|
this.on = this.on.bind(this);
|
|
this.off = this.off.bind(this);
|
|
this.connectPromise = null;
|
|
this.pendingListeners = new Map();
|
|
}
|
|
|
|
on(event, callback) {
|
|
// If socket is already connected, register the listener directly
|
|
if (this.socket.connected) {
|
|
this.socket.on(event, callback);
|
|
return;
|
|
}
|
|
|
|
// Store the listener to be registered when connection is established
|
|
if (!this.pendingListeners.has(event)) {
|
|
this.pendingListeners.set(event, new Set());
|
|
}
|
|
this.pendingListeners.get(event).add(callback);
|
|
|
|
// If not already connecting, initiate connection
|
|
if (!this.connectPromise) {
|
|
this.connect();
|
|
}
|
|
|
|
// Register the listener now, it will receive events once connected
|
|
this.socket.on(event, callback);
|
|
}
|
|
|
|
off(event, callback) {
|
|
// Remove from socket listeners
|
|
this.socket.off(event, callback);
|
|
|
|
// Remove from pending listeners if present
|
|
if (this.pendingListeners.has(event)) {
|
|
const listeners = this.pendingListeners.get(event);
|
|
listeners.delete(callback);
|
|
if (listeners.size === 0) {
|
|
this.pendingListeners.delete(event);
|
|
}
|
|
}
|
|
}
|
|
|
|
connect() {
|
|
if (this.connectPromise) return this.connectPromise;
|
|
|
|
this.connectPromise = new Promise((resolve, reject) => {
|
|
this.socket.connect();
|
|
|
|
this.socket.once('connect', () => {
|
|
resolve();
|
|
});
|
|
|
|
this.socket.once('connect_error', (error) => {
|
|
this.connectPromise = null;
|
|
reject(error);
|
|
});
|
|
});
|
|
|
|
return this.connectPromise;
|
|
}
|
|
|
|
emit(event, ...args) {
|
|
return new Promise((resolve, reject) => {
|
|
if (!this.socket.connected) {
|
|
// If not already connecting, start connection
|
|
if (!this.connectPromise) {
|
|
this.connect();
|
|
}
|
|
|
|
// Wait for connection before emitting
|
|
this.connectPromise
|
|
.then(() => {
|
|
this.socket.emit(event, ...args);
|
|
resolve();
|
|
})
|
|
.catch((error) => {
|
|
reject(error);
|
|
});
|
|
} else {
|
|
// Socket already connected, emit directly
|
|
this.socket.emit(event, ...args);
|
|
resolve();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// Create singleton instance
|
|
const socketManager = new SocketManager();
|
|
|
|
// Attach to window object
|
|
window.socketManager = socketManager;
|
|
|
|
export default socketManager;
|