Go & PHP JSON-RPC связи - PullRequest
       19

Go & PHP JSON-RPC связи

0 голосов
/ 02 мая 2018

Я пробую связь JSON-RPC между php и go.

Сервер GO из этого примера 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)
    }

}

и php клиент из примера этого репозитория 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'] . "\n";
} else {
    var_dump($result['data']);
}

Bur final У меня ошибка: HTTP / 1.1 400 Bad Request Я пытался также написать sleep(5) после подключения php, но безрезультатно? Также я попытался изменить с true на false на функцию stream_set_blocking($this->sockfp, false) https://github.com/ptcx/jsonrpc-client/blob/master/src/Connection/TcpConnection.php#L69 - безрезультатно. Я тред пишу GO клиент - он работает без проблем.

Помогите мне пожалуйста с моим php клиентом

1 Ответ

0 голосов
/ 03 мая 2018

Когда вы звоните rpc.HandleHTTP(), вы используете кодирование и декодирование гобов. Узнайте больше о гобах в: https://blog.golang.org/gobs-of-data и https://golang.org/pkg/encoding/gob/.

В файле https://golang.org/src/net/rpc/server.go вы можете прочитать это:

enter image description here

Чтобы использовать jsonrpc в Go, вы должны использовать кодек из пакета net / rpc / jsonrpc вместо net / rpc.

Пакет jsonrpc реализует JSON-RPC 1.0 ClientCodec и ServerCodec для пакета RPC. Для поддержки JSON-RPC 2.0 [...]

(Ссылка на источник: https://golang.org/pkg/net/rpc/jsonrpc/)

Так что выше, следуя коду в 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)
    }
}

На exec php client.php результат был:

enter image description here

Обновление: в php файле:

<?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'] . "\n";
} else {
    var_dump($result['data']);
}

?>

Надеюсь, это поможет !!

...