-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add JSONRPCSocket class to handle requests and long-running subscript…
…ions over sockets, added test client helpers for unit testing, added some initial unit tests
- Loading branch information
1 parent
a98733a
commit 56b4976
Showing
6 changed files
with
377 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { v4 as uuidv4 } from 'uuid'; | ||
import WebSocket from 'ws'; | ||
|
||
import type { JsonRpcRequest, JsonRpcResponse } from "./lib/json-rpc.js"; | ||
|
||
const CONNECT_TIMEOUT = 3_000; | ||
|
||
export class JSONRPCSocket { | ||
private isOpen = false; | ||
constructor(private socket: WebSocket) { | ||
socket.onopen = this.open; | ||
} | ||
|
||
static async connect(url: string): Promise<JSONRPCSocket> { | ||
|
||
const onclose = ():void => { | ||
console.log('json rpc close'); | ||
}; | ||
|
||
const onerror = (event: any):void => { | ||
console.log('json rpc error', event); | ||
}; | ||
|
||
const socket = new WebSocket(url); | ||
socket.onclose = onclose; | ||
socket.onerror = onerror; | ||
|
||
return new Promise<JSONRPCSocket>((resolve, reject) => { | ||
socket.on('open', () => { | ||
resolve(new JSONRPCSocket(socket)); | ||
}); | ||
|
||
setTimeout(() => reject, CONNECT_TIMEOUT); | ||
}); | ||
} | ||
|
||
open(): void { | ||
this.isOpen = true; | ||
} | ||
|
||
close(): void { | ||
this.isOpen = false; | ||
this.socket.close(); | ||
} | ||
|
||
/** | ||
* Sends a JSON-RPC request through the socket. You must subscribe to a message listener separately to capture the response. | ||
*/ | ||
send(request: JsonRpcRequest):void { | ||
return this.socket.send(Buffer.from(JSON.stringify(request))); | ||
} | ||
|
||
subscribe(request: JsonRpcRequest, listener: (response: JsonRpcResponse) => void): { close: () => void } { | ||
request.id ??= uuidv4(); | ||
|
||
const messageHandler = (event: { data: any }):void => { | ||
const jsonRpcResponse = JSON.parse(event.data.toString()) as JsonRpcResponse; | ||
if (jsonRpcResponse.id === request.id) { | ||
return listener(jsonRpcResponse); | ||
} | ||
}; | ||
|
||
this.socket.addEventListener('message', messageHandler); | ||
this.send(request); | ||
|
||
return { | ||
close: ():void => { | ||
this.socket.removeEventListener('message', messageHandler); | ||
} | ||
}; | ||
} | ||
|
||
async request(request: JsonRpcRequest): Promise<JsonRpcResponse> { | ||
return new Promise((resolve) => { | ||
request.id ??= uuidv4(); | ||
|
||
const handleResponse = (event: { data: any }):void => { | ||
const jsonRpsResponse = JSON.parse(event.data.toString()) as JsonRpcResponse; | ||
if (jsonRpsResponse.id === request.id) { | ||
this.socket.removeEventListener('message', handleResponse); | ||
return resolve(jsonRpsResponse); | ||
} | ||
}; | ||
|
||
this.socket.addEventListener('message', handleResponse); | ||
this.send(request); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.