J'essaie d'apprendre comment fonctionne JSON-RPC et de le tester en langage Go (golang). Le programme Go fonctionne très bien. Il fait ce qu'il devrait faire. Mais quand j'essaye de faire une requête brute via telnet, cela donne une erreur.JSON-RPC, "impossible de déformer l'objet"
Le travail et super simple serveur JSON-RPC est décrit ici:
// 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\r\n", 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\r\n", srv_addr, err) //dbg
}
log.Printf("Started RPC Handler at %s.\r\n", 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\r\n", err) //dbg
}
}
//------------------------------------------------------------------------------
Le travail et super simple code de client JSON-RPC suit:
// 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\r\n", 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\r\n", err) //dbg
}
// Show Results
fmt.Printf("[%d; %d] -> [%d].\r\n", args.A, args.B, result) //dbg
}
Encore une fois. Ce programme golang fonctionne bien.
Mais la prochaine chose que je ne peux pas comprendre.
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 {}"}
S'il vous plaît, donnez-moi quelques conseils ou la raison d'une telle erreur. Quel est le problème dans la demande brute?
Merci d'avance!
mise en œuvre actuelle du net/rpc/jsonrpc prendre 1 argument pour l'argument struct. https://github.com/golang/go/blob/5fea2ccc77eb50a9704fa04b7c61755fe34e1d95/src/net/rpc/jsonrpc/server.go#L91-L97 Si vous souhaitez passer des arguments nommés, passez en tant que tranche de struct. – mattn