dongsu3138
dongsu3138
2017-07-03 18:50

JSON-RPC,“无法解组对象”

已采纳

I am trying to learn how JSON-RPC works and am testing it in Go language (golang). The Go program works fine. It does what it should do. But when I try to make a raw request via telnet, it gives an error.

The working and super simple JSON-RPC server is described here:

    // rpc_json_server.go

    package main

    import (
        "log"
        "net"
        "net/http"
        "net/rpc"
        "net/rpc/jsonrpc"
    )

    //------------------------------------------------------------------------------
    // Types
    //------------------------------------------------------------------------------

    type Arithmetic int // Used as RPC Service called 'Arithmetic'

    type Arguments struct {
        A int
        B int
    }

    type Result int

    //------------------------------------------------------------------------------
    // Methods
    //------------------------------------------------------------------------------

    func (t *Arithmetic) Multiply(args *Arguments, res *Result) error {

        *res = Result(args.A * args.B)

        return nil
    }

    //------------------------------------------------------------------------------

    func main() {

        var srv *rpc.Server
        var err error
        var arith *Arithmetic
        var listener net.Listener
        var codec rpc.ServerCodec
        var srv_conntype, srv_host, srv_port, srv_addr, srv_path string
        var srv_debugPath string
        var connection net.Conn

        srv_conntype = "tcp"
        srv_host = "0.0.0.0"
        srv_port = "3000"
        srv_addr = srv_host + ":" + srv_port
        srv_path = "/"
        srv_debugPath = "/debug"

        // Create Server, register Service
        srv = rpc.NewServer()
        arith = new(Arithmetic)
        err = srv.Register(arith)
        if err != nil {
            log.Fatalf("Error. Service Format is not correct. %s
", err) //dbg
        }

        // Handle, listen
        srv.HandleHTTP(srv_path, srv_debugPath)
        listener, err = net.Listen(srv_conntype, srv_addr)
        if err != nil {
            log.Fatalf("Error. Can not listen on %s. %s
", srv_addr, err) //dbg
        }
        log.Printf("Started RPC Handler at %s.
", srv_addr) //dbg

        // Serve
        for {

            connection, err = listener.Accept()
            if err != nil {
                log.Fatal(err)
            }

            codec = jsonrpc.NewServerCodec(connection)

            go srv.ServeCodec(codec)
        }

        err = http.Serve(listener, nil)
        if err != nil {
            log.Fatalf("Serve Error. %s
", err) //dbg
        }
    }

    //------------------------------------------------------------------------------

The working and super simple JSON-RPC client's code is following:

    // rpc_json_client.go

    package main

    import (
        "fmt"
        "log"
        "net"
        "net/rpc"
        "net/rpc/jsonrpc"
    )

    //------------------------------------------------------------------------------
    // Types
    //------------------------------------------------------------------------------

    type Arithmetic int // Used as RPC Service called 'Arithmetic'

    type Arguments struct {
        A int
        B int
    }

    type Result int

    //------------------------------------------------------------------------------
    // Methods
    //------------------------------------------------------------------------------

    func main() {

        var err error
        var srv_conntype, srv_host, srv_port, srv_addr string
        //var srv_path string
        var client *rpc.Client
        var args Arguments
        var result Result
        var serviceName, methodName, funcName string
        var connection net.Conn

        srv_conntype = "tcp"
        srv_host = "0.0.0.0"
        srv_port = "3000"
        srv_addr = srv_host + ":" + srv_port
        //srv_path = "/"

        // Connect to RPC Server
        connection, err = net.Dial(srv_conntype, srv_addr)
        if err != nil {
            log.Fatalf("Error. Can not connect to %s. %s
", srv_addr, err) //dbg
        }
        defer connection.Close()

        // Client
        client = jsonrpc.NewClient(connection)

        // Prepare Call
        serviceName = "Arithmetic"
        methodName = "Multiply"
        funcName = serviceName + "." + methodName
        args.A = 7
        args.B = 8

        // Call remote Procedure
        err = client.Call(funcName, args, &result)
        if err != nil {
            log.Fatalf("Error. %s
", err) //dbg
        }

        // Show Results
        fmt.Printf("[%d; %d] -> [%d].
", args.A, args.B, result) //dbg
    }

Once again. This golang program works fine.

But the next thing I cannot understand.

    telnet localhost 3000
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    {
    "jsonrpc":"2.0", 
    "method":"Arithmetic.Multiply", 
    "params": { "A": 5, "B": 6 },
    "id":1
    }
    {"id":1,"result":null,"error":"json: cannot unmarshal object into Go value of type [1]interface {}"}

Please, give me some advice or the reason for such an error. What is wrong in the raw request?

Thanks in advance!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • douluhaikao93943 douluhaikao93943 4年前

    Your code seems fine.

    But in the request, params is expected to be an array containing the actual parameters.

    Try with the following payload and it should work:

    { 
      "jsonrpc":"2.0",
      "method":"Arithmetic.Multiply", 
      "params": [ { "A": 5, "B": 6 } ], 
      "id":1 
    } 
    

    (Note the "[" and "]" enclosing the actual param)

    点赞 评论 复制链接分享

相关推荐