RPC相关框架的使用方法

1.gRPC使用

下面的代码gRPC官网的使用例子

定于proto文件用于服务器和客户端交互的方法,请求参数和返回结果。

复制代码
syntax = "proto3";

option go_package = "google.golang.org/grpc/examples/helloworld/helloworld";
package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
复制代码


1.proto文件用来定义消息格式,这是一种高效轻便的结构化数据存储方式,可以用于数据通信,数据储存。
2.protoBuf与xml,json一样都是存数据,用于传输的数据存储方式,不过protoBuf需要用生成器protoc生成对应语言的代码。
3.protoBuf是二进制传输,适合小文件传输,解析效率比较快。

proto和thrift都是IDL接口定义语言,进行RPC就需要对方的接口是什么,需要传什么,返回的值是什么,IDL就是来定义这个,客户端和服务端都要有,而且得同一个。

 

客户端代码

复制代码
import pb "google.golang.org/grpc/examples/helloworld/helloworld"
type server struct {
    pb.UnimplementedGreeterServer
}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}

func main() {
    //1.监听端口
    lis, err := net.Listen("tcp", "localhost:8080")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    //2.创建grpc服务
    s := grpc.NewServer()
    //3.将pb的服务信息和server结构体注册进grpc服务s
    pb.RegisterGreeterServer(s, &server{})
    //4.开启服务
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

复制代码

 

先来看看运行逻辑
第三步就是 pb.RegisterGreeterServer(s, &server{})

相当于 s.RegisterService(&pb.Greeter_ServiceDesc, &server{})
将proto生成的Greeter_ServiceDesc 服务信息(方法和元数据等)和server结构体(待实现的方法)注册进grpc服务,这里用了两个map来保存methods,streams。

第二步跟第四步都是框架逻辑,后续再谈。

复制代码
var Greeter_ServiceDesc = grpc.ServiceDesc{
    ServiceName: "helloworld.Greeter",
    HandlerType: (*GreeterServer)(nil),
    Methods: []grpc.MethodDesc{
        {
            MethodName: "SayHello",
            Handler:    _Greeter_SayHello_Handler,
        },
    },
    Streams:  []grpc.StreamDesc{},
    Metadata: "examples/helloworld/helloworld/helloworld.proto",
}
复制代码

服务端代码

复制代码
import  pb "google.golang.org/grpc/examples/helloworld/helloworld"

func main() {
    //1.拨号连接
    conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    //2.用pb创建客户端client
    c := pb.NewGreeterClient(conn)
    //3.创建ctx
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()
    //4.调用pb方法
    r, err := c.SayHello(ctx, &pb.HelloRequest{Name:"Name to greet"})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Greeting: %s", r.GetMessage())
}
复制代码

第一步连接服务器,生成grpc的ClientConn
第二步创建pb结构体,里面带有定义的方法,同时通过pb的初始化方法将grpc的ClientConn放到greeterClient
第三步调用方法
这样pb用ClientConn的invoke方法(grpc框架的方法)来执行要远程调用的方法。

复制代码
func invoke(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error {
    cs, err := newClientStream(ctx, unaryStreamDesc, cc, method, opts...)
    if err != nil {
        return err
    }
    if err := cs.SendMsg(req); err != nil {
        return err
    }
    return cs.RecvMsg(reply)
}
复制代码

 

2.go kitex

定义完IDL后

复制代码
package main

import (
    "xx/echo"
    "xx/echo/echoservice"
)

type handler struct {}

func (handler) Echo(ctx context.Context, req *echo.Request) (r *echo.Response, err error) {
    //...
    return &echo.Response{ Msg: "world" }
}

func (handler) VisitOneway(ctx context.Context, req *echo.Request) (err error) {
    //...
    return nil
}

func main() {
    svr, err := echoservice.NewServer(handler{})
    if err != nil {
        panic(err)
    }
    svr.Run()
}
复制代码

client

复制代码
func main() {
    cli, err := echoservice.NewClient("destServiceName")
    if err != nil {
        panic(err)
    }
    req := echo.NewRequest()
    req.Msg = "hello"
    err = cli.VisitOneway(req)
    if err != nil {
        panic(err)
    }
}
复制代码

引用链接:https://www.cloudwego.io/zh/docs/kitex/tutorials/basic-feature/message_type/

 

3. phpRPC

复制代码
PHPRPC使用
server:
<?php
include ("phprpc/phprpc_server.php");
function HelloWorld() {
    return 'Hello World!';
}
$server = new PHPRPC_Server();
$server->add('HelloWorld');
$server->start();

client
<?php
include ("phprpc/phprpc_client.php");
$client = new PHPRPC_Client('http://127.0.0.1/server.php');
echo $client->HelloWorld();
?>
复制代码

可以看到服务寻址是通过创建client stub(客户端存根)的时候写入的。

4.php yar

复制代码
yar使用:
<?php
class API {
    public function api($parameter, $option = "foo") {
        return $parameter;
    }
    protected function client_can_not_see() {
    }
}
$service = new Yar_Server(new API());
$service->handle();
复制代码

 

可以看到go-rpc框架的使用方法都类似,即将生成的结构体带上方法,加入到rpc框架里面,由框架来进行调用和返回。

 

posted @   来杯王老吉  阅读(76)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示