feat: enhance RPC connection handling with disconnection error and event emitter improvements
This commit is contained in:
@@ -14,18 +14,31 @@ interface RPCConnectionEvents {
|
||||
closed: void;
|
||||
}
|
||||
|
||||
class CallResponseEmitter extends EventEmitter<{
|
||||
[id: string]: RPCPacket;
|
||||
}> {
|
||||
emitAll(packet: RPCPacket) {
|
||||
this.events.forEach(subscribers => {
|
||||
subscribers.forEach(fn => fn(packet));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class RPCConnection extends EventEmitter<RPCConnectionEvents> {
|
||||
|
||||
closed: boolean = false;
|
||||
|
||||
private callResponseEmitter = new EventEmitter<{
|
||||
[id: string]: RPCPacket;
|
||||
}>();
|
||||
private callResponseEmitter = new CallResponseEmitter();
|
||||
|
||||
constructor(public socket: SocketConnection) {
|
||||
super();
|
||||
socket.on('closed', () => {
|
||||
this.emit('closed');
|
||||
this.callResponseEmitter.emitAll(makeCallResponsePacket({
|
||||
status: 'error',
|
||||
requestPacketId: 'connection error',
|
||||
errorCode: RPCErrorCode.CONNECTION_DISCONNECTED,
|
||||
}));
|
||||
this.callResponseEmitter.removeAllListeners();
|
||||
this.closed = true;
|
||||
});
|
||||
@@ -68,6 +81,12 @@ export class RPCConnection extends EventEmitter<RPCConnectionEvents> {
|
||||
args: any[];
|
||||
timeout: number;
|
||||
}): Promise<any> {
|
||||
if (this.closed) {
|
||||
throw new RPCError({
|
||||
errorCode: RPCErrorCode.CONNECTION_DISCONNECTED,
|
||||
});
|
||||
}
|
||||
|
||||
const { fnPath, args } = options;
|
||||
const packet = makeCallPacket({
|
||||
fnPath,
|
||||
|
||||
@@ -9,6 +9,7 @@ export enum RPCErrorCode {
|
||||
HANDSHAKE_INCOMPLETE = -400,
|
||||
TIMEOUT_ERROR = -500,
|
||||
CALL_PROTOCOL_ERROR = -600,
|
||||
CONNECTION_DISCONNECTED = -700,
|
||||
}
|
||||
|
||||
export const RPC_ERROR_MESSAGES: Record<RPCErrorCode | number, string> = {
|
||||
@@ -22,6 +23,7 @@ export const RPC_ERROR_MESSAGES: Record<RPCErrorCode | number, string> = {
|
||||
[RPCErrorCode.HANDSHAKE_INCOMPLETE]: 'Handshake not completed',
|
||||
[RPCErrorCode.TIMEOUT_ERROR]: 'Request timeout',
|
||||
[RPCErrorCode.CALL_PROTOCOL_ERROR]: 'Call protocol error',
|
||||
[RPCErrorCode.CONNECTION_DISCONNECTED]: 'Connection disconnected',
|
||||
} as const;
|
||||
|
||||
export class RPCError extends Error {
|
||||
|
||||
@@ -2,7 +2,7 @@ type EventType = Record<string, any>;
|
||||
|
||||
export class BaseEventEmitter<T extends EventType> {
|
||||
|
||||
private events: Map<keyof T, Set<(args: any) => void>> = new Map();
|
||||
protected events: Map<keyof T, Set<(args: any) => void>> = new Map();
|
||||
|
||||
public on<K extends keyof T>(event: K, listener: (args: T[K]) => void) {
|
||||
this.addListener({ event, listener });
|
||||
|
||||
Reference in New Issue
Block a user