77 lines
1.6 KiB
TypeScript
77 lines
1.6 KiB
TypeScript
import net from 'net'
|
|
|
|
interface JsonRpcRequest {
|
|
jsonrpc: '2.0'
|
|
method: string
|
|
params?: any
|
|
id: number
|
|
}
|
|
|
|
interface JsonRpcResponse {
|
|
jsonrpc: '2.0'
|
|
id: number
|
|
result?: any
|
|
error?: { code: number; message: string; data?: any }
|
|
context?: any
|
|
}
|
|
|
|
export class JsonRpcClient {
|
|
private host: string
|
|
private port: number
|
|
private timeout: number
|
|
|
|
constructor(host: string = '127.0.0.1', port: number = 9504, timeout = 1000) {
|
|
this.host = host
|
|
this.port = port
|
|
this.timeout = timeout
|
|
}
|
|
|
|
async call(method: string, params?: any): Promise<any> {
|
|
const req: JsonRpcRequest = {
|
|
jsonrpc: '2.0',
|
|
method,
|
|
params,
|
|
id: Date.now(),
|
|
}
|
|
|
|
|
|
const message = JSON.stringify(req) + '\n'
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const client = new net.Socket()
|
|
let response = ''
|
|
|
|
client.setEncoding('utf-8')
|
|
const timer = setTimeout(() => {
|
|
client.destroy()
|
|
reject(new Error('RPC call timed out'))
|
|
}, this.timeout)
|
|
|
|
client.connect(this.port, this.host, () => {
|
|
client.write(message)
|
|
})
|
|
|
|
client.on('data', (data) => {
|
|
response += data.toString()
|
|
try {
|
|
const res: JsonRpcResponse = JSON.parse(response)
|
|
clearTimeout(timer)
|
|
client.end()
|
|
if (res.error) {
|
|
reject(new Error(res.error.message))
|
|
} else {
|
|
resolve(res.result)
|
|
}
|
|
} catch (e) {
|
|
// wait for more data
|
|
}
|
|
})
|
|
|
|
client.on('error', (err) => {
|
|
clearTimeout(timer)
|
|
reject(err)
|
|
})
|
|
})
|
|
}
|
|
}
|