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框架里面,由框架来进行调用和返回。
标签:nil,框架,err,grpc,helloworld,server,pb,RPC,方法 From: https://www.cnblogs.com/gz-wod/p/17291281.html