Ocaml-rpc example

Hi!

I’m trying to create a minimal working example of a Json-RPC with rpclib. So far I have the following:

module MyServer (R : Idl.RPC) = struct 
  open R 
  open Idl 

  let description = Interface.{
    name = ""; 
    namespace = Some ""; 
    description = [""]; 
    version = 1, 0, 0; 
  }

  let implementation = implement description 

  let i = Param.mk Rpc.Types.int 
  let e1 = Idl.DefaultError.err 

  let add = declare "add" [] (i @-> i @-> returning i e1) 
end 

module M = Idl.IdM  
module MyIdl = Idl.Make (M) 
module Server = MyServer (MyIdl.GenServer ()) 

let _ = 
  Server.add (fun a b -> MyIdl.ErrM.return (a+b)); 
  let rpc_func = MyIdl.server Server.implementation in 
  
  let rec loop _ = 
    let open M in 
    match In_channel.input_line In_channel.stdin with 
    | None -> loop () 
    | Some inp ->
      if String.equal "" inp then loop () else 
      let call = Jsonrpc.call_of_string inp in 
      Printf.printf "%s\n" (Rpc.string_of_call call); 
      rpc_func call >>= fun res -> Jsonrpc.string_of_response res |> return 
      >>= fun res -> Printf.fprintf Out_channel.stdout "%s\n" res;
      loop ()
  in 
  loop () 

If I run the above code from the command line it seems to wait for an input as expected. If I type in

{"jsonrpc":"2.0","method":"add","params":[2,3],"id":1}

followed by a return I get the following:

-> add(I(2),I(3))
Fatal error: exception Idl.UnknownMethod("add")

I’m a bit at a loss why that is happening, as it seems to parse the incoming json call correctly.

Thanks for any input :slight_smile:

Hi @nhuber

I’m not an expert on Rpclib but I think the issue is that it tries to do a bit of name-spacing and you have passed Some "" instead of None – Rpclib doesn’t check for the empty string so your method becomes callable under ".add" (i.e. "" ^ "." ^ "method"). If you change Some "" to None your example works or if you change your input to

{"jsonrpc":"2.0","method":".add","params":[2,3],"id":1}

it also works. Note, I had to throw in a flush operation to your final print statement to see things in the terminal (i.e. Printf.fprintf Out_channel.stdout "%s\n%!" res). Hope that helps :))

Perfect, thanks! I find the documentation of rpclib a bit hard to decipher, so I had no idea what the namespace member of the description actually does :slight_smile:

Now everything works perfectly!