Skip to content

Commit

Permalink
Add onProcessMessage hook to client
Browse files Browse the repository at this point in the history
  • Loading branch information
jangko committed Jan 7, 2024
1 parent 20b4c9a commit 09d1281
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 1 deletion.
8 changes: 8 additions & 0 deletions json_rpc/client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type
awaiting*: Table[RequestId, Future[JsonString]]
lastId: int
onDisconnect*: proc() {.gcsafe, raises: [].}
onProcessMessage*: proc(client: RpcClient, line: string):
Result[bool, string] {.gcsafe, raises: [].}

GetJsonRpcRequestHeaders* = proc(): seq[(string, string)] {.gcsafe, raises: [].}

Expand Down Expand Up @@ -67,6 +69,12 @@ method close*(client: RpcClient): Future[void] {.base, gcsafe, async.} =
doAssert(false, "`RpcClient.close` not implemented")

proc processMessage*(client: RpcClient, line: string): Result[void, string] =
if client.onProcessMessage.isNil.not:
let fallBack = client.onProcessMessage(client, line).valueOr:
return err(error)
if not fallBack:
return ok()

# Note: this doesn't use any transport code so doesn't need to be
# differentiated.
try:
Expand Down
3 changes: 2 additions & 1 deletion tests/all.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ import
testhook,
test_jrpc_sys,
test_router_rpc,
test_callsigs
test_callsigs,
test_client_hook
76 changes: 76 additions & 0 deletions tests/test_client_hook.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# json-rpc
# Copyright (c) 2023 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.

import
unittest2,
../json_rpc/rpcclient,
../json_rpc/rpcserver

createRpcSigsFromNim(RpcClient):
proc get_Banana(id: int): int

proc installHandlers(s: RpcServer) =
s.rpc("get_Banana") do(id: int) -> JsonString:
if id == 99:
return "123".JsonString
elif id == 100:
return "\"stop\"".JsonString
else:
return "\"error\"".JsonString

type
Shadow = ref object
something: int

proc setupClientHook(client: RpcClient): Shadow =
var shadow = Shadow(something: 0)
client.onProcessMessage = proc(client: RpcClient, line: string):
Result[bool, string] {.gcsafe, raises: [].} =

try:
let m = JrpcConv.decode(line, JsonNode)
if m["result"].kind == JString:
if m["result"].str == "stop":
shadow.something = 123
return ok(false)
else:
shadow.something = 77
return err("not stop")

return ok(true)
except CatchableError as exc:
return err(exc.msg)
shadow

suite "test callsigs":
var server = newRpcHttpServer(["127.0.0.1:0"])
server.installHandlers()
var client = newRpcHttpClient()
let shadow = client.setupClientHook()

server.start()
waitFor client.connect("http://" & $server.localAddress()[0])

test "client onProcessMessage hook":
let res = waitFor client.get_Banana(99)
check res == 123
check shadow.something == 0

expect JsonRpcError:
let res2 = waitFor client.get_Banana(123)
check res2 == 0
check shadow.something == 77

expect InvalidResponse:
let res2 = waitFor client.get_Banana(100)
check res2 == 0
check shadow.something == 123

waitFor server.stop()
waitFor server.closeWait()

0 comments on commit 09d1281

Please sign in to comment.