node-mole-rpc icon indicating copy to clipboard operation
node-mole-rpc copied to clipboard

MoleClient: allow sending Object as params

Open yoursunny opened this issue 5 years ago • 2 comments

The JSON-RPC 2.0 specification allows params to be either an Array or an Object. However, current MoleClient implementation can only accept array; it would reject objects unless it has an .length property. This patch allows MoleClient to accept an Object as params.

This is useful for interacting with RPC servers written in Go language, because the official Go guides for net/rpc package default to using objects.


This feature has been tested with the following snippet:

client.js

const MoleClient = require('mole-rpc/MoleClient');
const TransportClientWS = require('mole-rpc-transport-ws/TransportClientWS');
const WebSocket = require('ws');

async function main() {
  const client = new MoleClient({
    requestTimeout: 1000,
    transport: new TransportClientWS({
      wsBuilder: () => new WebSocket(`ws://192.168.5.13:7000`)
    })
  });

  try {
    const result = await client.callMethod("X.Sum", { A: 1, B: 2 });
    console.log(result);
    const results = await client.runBatch([
      ["X.Sum", { A: 10, B: 20 }],
      ["X.Sum", { A: 100, B: 200 }],
    ]);
    console.log(results);
  } catch (err) {
    console.error(err);
  }
}

main().then(console.log, console.error);

server.go

package main

import (
	"context"
	"errors"
	"log"
	"net/http"
	"net/rpc"

	"github.com/powerman/rpc-codec/jsonrpc2"
	"nhooyr.io/websocket"
)

type X struct{}

type SumArgs struct {
  A int
  B int
}

func (X) Sum(arg SumArgs, res *int) error {
	*res = arg.A + arg.B
	return nil
}

func main() {
	rpc.Register(X{})

	fn := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		c, err := websocket.Accept(w, r, nil)
		if err != nil {
			log.Println(err)
			return
		}
		defer c.Close(websocket.StatusInternalError, "")
		jsonrpc2.ServeConn(websocket.NetConn(context.Background(), c, websocket.MessageText))
		c.Close(websocket.StatusNormalClosure, "")
	})

	err := http.ListenAndServe("0.0.0.0:7000", fn)
	log.Fatal(err)
}

yoursunny avatar Jun 07 '20 19:06 yoursunny

Hey @koorchik can you review and merge?

yoursunny avatar Jul 18 '20 01:07 yoursunny

After a long time without action from the repository owner, I have decided to publish my patches in a fork: @yoursunny/mole-rpc. If anyone else is affected from this bug, you can try my fork.

yoursunny avatar Sep 06 '20 14:09 yoursunny