各种语言最常见的就是 hello world , 每次感觉看完 hello world之后,感觉就要say goodbye
syntax = "proto3"; // 指定使用的版本,proto1已经不用了 // 下面这些参数都是转译成java语言使用的 option java_multiple_files = true; option java_package = "io.grpc.examples.helloworld"; option java_outer_classname = "HelloWorldProto"; package helloworld; // 这里面就是对grpc 的server里面的一些定义. service Greeter { // 这里面是调用rpc的方法名称,就是 func(参数)return 参数{} rpc SayHello (HelloRequest) returns (HelloReply) {} } // 下面就是指定的请求参数结构 message HelloRequest { // string就是指定这个参数的的类型, name就是字段名。 1 就是一个序号 string name = 1; } // 这就是返回结构的机构, message HelloReply { string message = 1; }
上面文件使用proto tool工具就可以生成对应的文件,在go中会生成一个pb.go的文件,python中会生成_pb.py, pb_grpc.py文件,所以说还是go的一家人
下面就是用go写的grpc的服务package mai
import ( "context" "log" "net" "google.golang.org/grpc" pb "google.golang.org/grpc/examples/helloworld/helloworld" ) const ( port = ":50051" // 指定的端口号 ) // server is used to implement helloworld.GreeterServer.
// 定义一个结构体,然后在定义方法最开始位置传入,就相当于为这个对象实现了某个方法,可以想象成python的类 type server struct{} // SayHello implements helloworld.GreeterServer
// 这次的rpc中只有这一个方法, ctx就是上下文, in就是之前在proto中定义的请求参数, helloreply就是返回参数的结构 func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { log.Printf("Received: %v", in.Name)
return &pb.HelloReply{Message: "Hello " + in.Name}, nil } func main() {
// 首先起一个tcp协议,端口号就是之前定义的 lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) }
// 起一个实例 s := grpc.NewServer()
// 将写的服务进行注册 pb.RegisterGreeterServer(s, &server{})
// 开启服务 if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }
client端
package main import ( "context" "log" "os" "time" "google.golang.org/grpc" pb "google.golang.org/grpc/examples/helloworld/helloworld" ) // 就是定义客户端的tcp协议端口号 const ( address = "localhost:50051" defaultName = "world" ) func main() { // Set up a connection to the server.
// 非阻塞状态下,不做真正连接,只控制作用, WithInsecure返回一个DialOption,它在传输过程中不保证安全。除非设置WithInsecure,否则grpc.Dial必须指定安全选项
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err) }
// 函数完毕,关闭
defer conn.Close()
// 这个就是proto生成的文件中的初始化函数
c := pb.NewGreeterClient(conn) // Contact the server and print out its response. name := defaultName if len(os.Args) > 1 { name = os.Args[1] }
// 设置超时关闭 context.Background{}就是一个空白的上下文,1S ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel()
// 直接调用函数 r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", r.Message) }
hello world比较简单,没啥内容,就是调用一个函数,然后拿到返回值。
原文:https://www.cnblogs.com/yangshixiong/p/12112179.html