添加一些功能
然后写一个客户端与前面的服务器进行交互,创建一个 client.proto
文件:
syntax = "proto3"; // 协议为proto3 package chat; // 定义发送请求信息 message Message { // 定义发送的参数 // 参数类型 参数名 标识号(不可重复) string body = 1; } // 定义我们的服务(可定义多个服务,每个服务可定义多个接口) service ChatService { rpc SayHello(Message) returns (Message) {} }
这个 .proto
文件公开了我们的 ChatService
,它具有一个单独的 SayHello
函数,可以由任何用任何语言编写的 gRPC 客户端调用。
这些 .proto
定义通常在各种形状和大小的客户端之间共享,以便它们可以生成自己的代码来与我们的 gRPC 服务器通信。
让我们使用 protoc 工具生成 Go 特定的 gRPC 代码:
$ protoc --go_out=plugins=grpc:chat chat.proto
您会看到这将生成一个 chat/chat.pb.go
文件,该文件将包含生成的代码,以便我们在代码中轻松调用。让我们更新我们的 server.go
来注册我们的 ChatService,如下所示:
package main import ( "fmt" "log" "net" "github.com/tutorialedge/go-grpc-beginners-tutorial/chat" "google.golang.org/grpc" ) func main() { fmt.Println("Go gRPC Beginners Tutorial!") lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 9000)) if err != nil { log.Fatalf("failed to listen: %v", err) } s := chat.Server{} grpcServer := grpc.NewServer() chat.RegisterChatServiceServer(grpcServer, &s) if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %s", err) } }
然后我们将必须定义 SayHello 方法,该方法将接收一条消息,读取消息的正文,然后返回它自己的消息:
package chat import ( "log" "golang.org/x/net/context" ) type Server struct { } func (s *Server) SayHello(ctx context.Context, in *Message) (*Message, error) { log.Printf("Receive message body from client: %s", in.Body) return &Message{Body: "Hello From the Server!"}, nil }
如果我们想为我们的 gRPC 服务器定义更高级的功能,那么我们可以通过定义一个基于我们的 Server 结构构建的新方法来实现,然后将该函数的名称添加到我们的 chat.proto
文件中,以便我们的应用程序可以将其公开为某种东西其他 gRPC 客户端可以访问。
完成这些最终更改后,让我们尝试运行我们的服务器:
$ go run server.go Go gRPC Beginners Tutorial!
惊人的!我们现在在我们的机器上的 localhost:8000
上启动并运行了一个崭新的、闪亮的新 gRPC 服务器!
在 Go 中构建 gRPC 客户端
现在我们的服务器已经启动并运行了,让我们看看如何构建一个能够与之交互的简单客户端。更新一下 client.go
文件:
package main import ( "log" "golang.org/x/net/context" "google.golang.org/grpc" "github.com/tutorialedge/go-grpc-beginners-tutorial/chat" ) func main() { var conn *grpc.ClientConn conn, err := grpc.Dial(":8000", grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %s", err) } defer conn.Close() c := chat.NewChatServiceClient(conn) response, err := c.SayHello(context.Background(), &chat.Message{Body: "Hello From Client!"}) if err != nil { log.Fatalf("Error when calling SayHello: %s", err) } log.Printf("Response from server: %s", response.Body) }
当我们运行它时,我们应该看到我们的客户端从服务器收到了一个非常好的 Hello 消息,如下所示:
$ go run client.go 2022/07/07 23:23:01 Response from server: Hello From the Server!
我们已经成功创建了一个非常简单的 gRPC 客户端,它现在可以与我们的新 gRPC 服务器通信!
总结
通过本文我们已经了解了如何在 Go 中构建一个简单的 gRPC 客户端和服务器。我们构建了一个基本服务器,它接受来自客户端的传入消息,然后向这些客户端返回响应。