hyperf與go基於jsonrpc2.0通信

前言

現在微服務很流行,很多的語言都有自己的rpc框架,在同一框架內的微服務之間通信很方便,筆者工作時用到的框架是hyperf,自帶jsonrpc、grpc組件,grpc用起來略感繁瑣,調試起來也不方便,因此選用jsonrpc-http,損失些許通信成本在可接受範圍之內,能用postman調試實在是太方便了。
隨着業務和團隊的不斷髮展,開始有多語言開發需求,我們的另一個項目是用go搭建的,hyperf與go之間也打算用jsonrpc,go自帶jsonrpc包,但是是jsonrpc1.0的,與hyperf不兼容,經過努力,找到一個jsonrpc2.0的包(go-jsonrpc),與hyperf完美兼容。

hyperf爲服務端,go爲客戶端

hyperf服務端

  • comfig/autoload/server.php
<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  [email protected]
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
use Hyperf\Server\Server;
use Hyperf\Server\SwooleEvent;

return [
    'mode' => SWOOLE_PROCESS,
    'servers' => [
        [
            'name' => 'http',
            'type' => Server::SERVER_HTTP,
            'host' => '0.0.0.0',
            'port' => 9501,
            'sock_type' => SWOOLE_SOCK_TCP,
            'callbacks' => [
                SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
            ],
        ],
        [
            'name' => 'jsonrpc-http',
            'type' => Server::SERVER_HTTP,
            'host' => '0.0.0.0',
            'port' => (int)env('SERVICE_HTTP_PORT', 3232),
            'sock_type' => SWOOLE_SOCK_TCP,
            'callbacks' => [
                SwooleEvent::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'],
            ],
        ],
    ],
    'settings' => [
        'enable_coroutine' => true,
        'worker_num' => swoole_cpu_num(),
        'pid_file' => BASE_PATH . '/runtime/hyperf.pid',
        'open_tcp_nodelay' => true,
        'max_coroutine' => 100000,
        'open_http2_protocol' => true,
        'max_request' => 100000,
        'socket_buffer_size' => 2 * 1024 * 1024,
        'buffer_output_size' => 2 * 1024 * 1024,
    ],
    'callbacks' => [
        SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
        SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'],
        SwooleEvent::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'],
    ],
];
  • app/JsonRpc/PhpService.php
<?php


namespace App\JsonRpc;

use Hyperf\RpcServer\Annotation\RpcService;

/**
 * 注意,如希望通過服務中心來管理服務,需在註解內增加 publishTo 屬性
 * @RpcService(name="PhpService", protocol="jsonrpc-http", server="jsonrpc-http")
 */
class PhpService
{
   
   
    public function add(int $a, int $b)
    {
   
   
        return $a + $b;
    }
}

go客戶端

package main

import (
	"fmt"
	go_jsonrpc "github.com/iloveswift/go-jsonrpc"
	"go-jsonrpc-skeleton/jsonrpc"
)

func main() {
   
   
	result := new(jsonrpc.Result)
	c, _ := go_jsonrpc.NewClient("http", "127.0.0.1", "3232")
	err := c.Call("php/add", jsonrpc.Params{
   
   1, 6}, result, false)
	// data sent: {"id":"1604283212","jsonrpc":"2.0","method":"php/add","params":{"a":1,"b":6}}
	// data received: {"id":"1604283212","jsonrpc":"2.0","result":7}
	fmt.Println(err) // nil
	fmt.Println(*result) // 7
}

go爲服務端,hyperf爲客戶端

go服務端

  • jsonrpc/go_service.go
package jsonrpc

type Go struct {
   
   }

type Params struct {
   
   
	A int `json:"a"`
	B int `json:"b"`
}

type Result = int

func (*Go) Sub(params *Params, result *Result) error {
   
   
	a := params.A - params.B
	*result = interface{
   
   }(a).(Result)
	return nil
}
  • main.go
package main

import (
	go_jsonrpc "github.com/iloveswift/go-jsonrpc"
	"go-jsonrpc-skeleton/jsonrpc"
)

func main() {
   
   
	s, _ := go_jsonrpc.NewServer("http", "127.0.0.1", "3233")
	s.Register(new(jsonrpc.Go))
	s.Start()
}

hyperf客戶端

  • comfig/autoload/services.php
<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  [email protected]
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
return [
    'consumers' => [
        [
            'name' => 'GoService',
            'nodes' => [
                ['host' => '127.0.0.1', 'port' => 3233]
            ],
        ],
    ],
];

  • app/JsonRpc/GoServiceConsumer.php
<?php


namespace App\JsonRpc;

use Hyperf\RpcClient\AbstractServiceClient;

class GoServiceConsumer extends AbstractServiceClient
{
   
   
    /**
     * 定義對應服務提供者的服務名稱
     * @var string
     */
    protected $serviceName = 'GoService';

    /**
     * 定義對應服務提供者的服務協議
     * @var string
     */
    protected $protocol = 'jsonrpc-http';

    public function Sub(int $a, int $b): int
    {
   
   
        return $this->__request(__FUNCTION__, compact('a', 'b'));
    }
}

Demo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章