diff --git a/json_rpc.nimble b/json_rpc.nimble index 3e46477..2c67cce 100644 --- a/json_rpc.nimble +++ b/json_rpc.nimble @@ -12,7 +12,7 @@ requires "nim >= 0.17.3", "chronos", "httputils", "chronicles", - "news", + "news >= 0.2 & < 0.3", "chronicles", "json_serialization" diff --git a/json_rpc/client.nim b/json_rpc/client.nim index a37369b..ea3437b 100644 --- a/json_rpc/client.nim +++ b/json_rpc/client.nim @@ -10,6 +10,7 @@ type awaiting*: Table[ClientId, Future[Response]] nextId: ClientId methodHandlers: Table[string, proc(j: JsonNode) {.gcsafe.}] + onDisconnect*: proc() {.gcsafe.} Response* = tuple[error: bool, result: JsonNode] diff --git a/json_rpc/clients/websocketclient.nim b/json_rpc/clients/websocketclient.nim index 4f5a2c9..4924b54 100644 --- a/json_rpc/clients/websocketclient.nim +++ b/json_rpc/clients/websocketclient.nim @@ -1,4 +1,4 @@ -import ../client, chronos, tables, json, strtabs, chronicles +import ../client, chronos, tables, json, strtabs const newsUseChronos = true include news @@ -33,17 +33,29 @@ method call*(self: RpcWebSocketClient, name: string, result = await newFut proc processData(client: RpcWebSocketClient) {.async.} = - while true: + var error: ref Exception + try: while true: var value = await client.transport.receivePacket() if value == "": # transmission ends - client.transport.close() break client.processMessage(value) - # async loop reconnection and waiting - client.transport = await newWebSocket(client.uri) + except CatchableError as e: + error = e + + client.transport.close() + client.transport = nil + + if client.awaiting.len != 0: + if error.isNil: + error = newException(IOError, "Transport was closed while waiting for response") + for k, v in client.awaiting: + v.fail(error) + client.awaiting.clear() + if not client.onDisconnect.isNil: + client.onDisconnect() proc connect*(client: RpcWebSocketClient, uri: string, headers: StringTableRef = nil) {.async.} = var headers = headers @@ -56,11 +68,7 @@ proc connect*(client: RpcWebSocketClient, uri: string, headers: StringTableRef = client.transport = await newWebSocket(uri, headers) client.uri = uri client.loop = processData(client) - client.loop.addCallback do(data: pointer): - if client.loop.failed: - let err = client.loop.readError() - error "websocket rpc", msg = err.msg, stacktrace = err.getStackTrace() method close*(client: RpcWebSocketClient) {.async.} = - # TODO: Stop the processData loop - client.transport.close() + if not client.transport.isNil: + client.loop.cancel() diff --git a/tests/ethprocs.nim b/tests/ethprocs.nim index f34b3b3..0a487f5 100644 --- a/tests/ethprocs.nim +++ b/tests/ethprocs.nim @@ -41,7 +41,7 @@ proc addEthRpcs*(server: RpcServer) = ## Returns the SHA3 result of the given string. # TODO: Capture error on malformed input var rawData: seq[byte] - rawData = data.string.fromHex + rawData = nimcrypto.fromHex(data.string) # data will have 0x prefix result = hexDataStr "0x" & $keccak_256.digest(rawData)