dongyuzhu2244
2018-05-02 19:36
浏览 75
已采纳

Go和PHP JSON-RPC通信

I try communication JSON-RPC between php and go.

Server GO from this example https://golang.org/pkg/net/rpc/

package main

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

type Args struct {
    A, B int
}

type Quotient struct {
    Quo, Rem int
}

type Arith int

func (t *Arith) Multiply(args *Args, reply *int) error {
    *reply = args.A * args.B
    return nil
}

func (t *Arith) Divide(args *Args, quo *Quotient) error {
    if args.B == 0 {
        return errors.New("divide by zero")
    }
    quo.Quo = args.A / args.B
    quo.Rem = args.A % args.B
    return nil
}


func main() {
    arith := new(Arith)
    rpc.Register(arith)
    rpc.HandleHTTP()
    l, e := net.Listen("tcp", ":4444")
    if e != nil {
        log.Fatal("listen error:", e)
    }
//  go http.Serve(l, nil)

    err:= http.Serve(l, nil)
    if err != nil {
        log.Fatalf("Error serving: %s", err)
    }

}

and php client from example this repository https://github.com/ptcx/jsonrpc-client:

require 'vendor/autoload.php';

$client = new JRClient\Client('tcp', '127.0.0.1:4444');
sleep(5);
$result = $client->call('Arith.Multiply', ['A' => 3, "B" => 4], 1000);
if ($result['error']) {
    echo $result['errorMsg'] . "
";
} else {
    var_dump($result['data']);
}

Bur final I have error: HTTP/1.1 400 Bad Request I tried also write sleep(5) after php connect but no result? Also I tried change from true on false into function stream_set_blocking($this->sockfp, false) https://github.com/ptcx/jsonrpc-client/blob/master/src/Connection/TcpConnection.php#L69 - no result. I treed write GO client - it is worked without problem.

Help me please with my php client

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • du1462 2018-05-03 00:13
    已采纳

    When you call rpc.HandleHTTP(), you are using gobs encode and decode. Read more about gobs in: https://blog.golang.org/gobs-of-data and https://golang.org/pkg/encoding/gob/.

    In file https://golang.org/src/net/rpc/server.go you can read this:

    enter image description here

    To use jsonrpc in Go, you must use the codec from package net/rpc/jsonrpc instead of net/rpc.

    Package jsonrpc implements a JSON-RPC 1.0 ClientCodec and ServerCodec for the rpc package. For JSON-RPC 2.0 support [...]

    (Ref. source: https://golang.org/pkg/net/rpc/jsonrpc/)

    So above following the code in main.go:

    func main() {
        //arith instance
        arith := new(Arith)
    
        //make listen in 127.0.0.1:4444
        l, e := net.Listen("tcp", ":4444")
        if e != nil {
            log.Fatal("listen error:", e)
        }
        defer l.Close()
    
        //instance rpc server
        rpcserver := rpc.NewServer()
        rpcserver.Register(arith)
        //updated for multiples requests
        for {
            //block until acceptation of client
            c, e := l.Accept()
            if e != nil {
              log.Fatal("accept error:", e)
            }
            //instance codec
            jsoncodec := jsonrpc.NewServerCodec(c)
            rpcserver.ServeCodec(jsoncodec)
        }
    }
    

    On exec php client.php the result was:

    enter image description here

    Update: in php file:

    <?php
    //imports
    require 'vendor/autoload.php';
    //instance client
    $client = new JRClient\Client('tcp', '127.0.0.1:4444');
    
    //sleep(5); <<-- remove
    
    //call method 'Arith.Multiply'
    $result = $client->call('Arith.Multiply', ['A' => 3, "B" => 4], 1000);
    if ($result['error']) {
        echo $result['errorMsg'] . "
    ";
    } else {
        var_dump($result['data']);
    }
    
    ?>
    

    Hope this helps!!

    打赏 评论

相关推荐 更多相似问题