Go Zero 与复杂.proto文件:构建强大的游戏服务架构

打印 上一主题 下一主题

主题 839|帖子 839|积分 2517




一、引言


在游戏开辟中,高效且可扩展的后端服务架构至关紧张。Go Zero 框架凭借其强大的功能,特殊是基于.proto文件的自动代码生成,为我们提供了一种高效的开辟方式。本文将深入探讨一个更复杂的.proto文件示例,并展示如何利用它在 Go Zero 中构建游戏服务架构。

二、.proto文件概述


我们的.proto文件界说了多个服务,涵盖了游戏中的关键功能模块。以下是其主要内容:

1. 用户服务(UserService)




  • 功能:提供对用户信息的获取和更新操纵。
  • 方法

    • GetUser(GetUserRequest) returns (GetUserResponse):根据用户 ID 获取用户具体信息。
    • UpdateUser(UpdateUserRequest) returns (UpdateUserResponse):更新用户的用户名和邮箱等信息。

  • 哀求和响应消息

    • GetUserRequest包罗一个user_id字段,用于指定要获取的用户 ID。
    • GetUserResponse包罗user_id、username和email字段,返回用户的具体信息。
    • UpdateUserRequest包罗要更新的用户 ID、用户名和邮箱等信息。
    • UpdateUserResponse包罗一个success字段,体现更新是否成功。


2. 物品服务(ItemService)




  • 功能:管理游戏中的物品,包括获取物品信息和创建新物品。
  • 方法

    • GetItem(GetItemRequest) returns (GetItemResponse):根据物品 ID 获取物品具体信息。
    • CreateItem(CreateItemRequest) returns (CreateItemResponse):创建一个新的物品。

  • 哀求和响应消息

    • GetItemRequest包罗一个item_id字段,用于指定要获取的物品 ID。
    • GetItemResponse包罗item_id、name和quantity字段,返回物品的具体信息。
    • CreateItemRequest包罗物品的名称和数量等信息。
    • CreateItemResponse包罗新创建物品的 ID 和一个success字段,体现创建是否成功。


3. 任务服务(QuestService)




  • 功能:处置惩罚游戏中的任务,包括获取任务信息和完成任务。
  • 方法

    • GetQuest(GetQuestRequest) returns (GetQuestResponse):根据任务 ID 获取任务具体信息。
    • CompleteQuest(CompleteQuestRequest) returns (CompleteQuestResponse):完成一个任务。

  • 哀求和响应消息

    • GetQuestRequest包罗一个quest_id字段,用于指定要获取的任务 ID。
    • GetQuestResponse包罗quest_id、name和description字段,返回任务的具体信息。
    • CompleteQuestRequest包罗要完成的任务 ID。
    • CompleteQuestResponse包罗一个success字段和reward字段,分别体现完成是否成功和完成任务后的夸奖。

  1. syntax = "proto3";
  2. package mygame;
  3. // 用户服务
  4. service UserService {
  5.     rpc GetUser(GetUserRequest) returns (GetUserResponse);
  6.     rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse);
  7. }
  8. // 用户请求和响应消息
  9. message GetUserRequest {
  10.     string user_id = 1;
  11. }
  12. message GetUserResponse {
  13.     string user_id = 1;
  14.     string username = 2;
  15.     string email = 3;
  16. }
  17. message UpdateUserRequest {
  18.     string user_id = 1;
  19.     string username = 2;
  20.     string email = 3;
  21. }
  22. message UpdateUserResponse {
  23.     bool success = 1;
  24. }
  25. // 物品服务
  26. service ItemService {
  27.     rpc GetItem(GetItemRequest) returns (GetItemResponse);
  28.     rpc CreateItem(CreateItemRequest) returns (CreateItemResponse);
  29. }
  30. // 物品请求和响应消息
  31. message GetItemRequest {
  32.     string item_id = 1;
  33. }
  34. message GetItemResponse {
  35.     string item_id = 1;
  36.     string name = 2;
  37.     int32 quantity = 3;
  38. }
  39. message CreateItemRequest {
  40.     string name = 1;
  41.     int32 quantity = 2;
  42. }
  43. message CreateItemResponse {
  44.     string item_id = 1;
  45.     bool success = 2;
  46. }
  47. // 任务服务
  48. service QuestService {
  49.     rpc GetQuest(GetQuestRequest) returns (GetQuestResponse);
  50.     rpc CompleteQuest(CompleteQuestRequest) returns (CompleteQuestResponse);
  51. }
  52. // 任务请求和响应消息
  53. message GetQuestRequest {
  54.     string quest_id = 1;
  55. }
  56. message GetQuestResponse {
  57.     string quest_id = 1;
  58.     string name = 2;
  59.     string description = 3;
  60. }
  61. message CompleteQuestRequest {
  62.     string quest_id = 1;
  63. }
  64. message CompleteQuestResponse {
  65.     bool success = 1;
  66.     string reward = 2;
  67. }
复制代码

三、使用 Go Zero 工具生成代码


1. 安装goctl


可以通过以下下令安装goctl:

  1. go install github.com/zeromicro/go-zero/tools/goctl@latest
复制代码

2. 生成代码


假设上面的.proto文件名为game.proto,位于当前目次下。可以使用以下下令生成服务端代码:

  1. goctl rpc protoc game.proto --go_out=. --go-grpc_out=. --zrpc_out=.
复制代码

这将生成多个文件,主要按照服务进行区分:



  • 对于每个服务,会生成一个对应的服务实现文件。例如,会有user_service.go、item_service.go和quest_service.go,分别包罗各自服务的方法实现。


  1. // user_service.go
  2. type UserService struct{}
  3. func (s *UserService) GetUser(ctx context.Context, in *GetUserRequest) (*GetUserResponse, error) {
  4.     // 实现获取用户逻辑
  5.     return &GetUserResponse{UserID: in.UserID, Username: "example_username", Email: "example@example.com"}, nil
  6. }
  7. func (s *UserService) UpdateUser(ctx context.Context, in *UpdateUserRequest) (*UpdateUserResponse, error) {
  8.     // 实现更新用户逻辑
  9.     return &UpdateUserResponse{Success: true}, nil
  10. }
复制代码

  1. // item_service.go
  2. type ItemService struct{}
  3. func (s *ItemService) GetItem(ctx context.Context, in *GetItemRequest) (*GetItemResponse, error) {
  4.     // 实现获取物品逻辑
  5.     return &GetItemResponse{ItemID: in.ItemID, Name: "example_item", Quantity: 10}, nil
  6. }
  7. func (s *ItemService) CreateItem(ctx context.Context, in *CreateItemRequest) (*CreateItemResponse, error) {
  8.     // 实现创建物品逻辑
  9.     return &CreateItemResponse{ItemID: "new_item_id", Success: true}, nil
  10. }
复制代码

  1. // quest_service.go
  2. type QuestService struct{}
  3. func (s *QuestService) GetQuest(ctx context.Context, in *GetQuestRequest) (*GetQuestResponse, error) {
  4.     // 实现获取任务逻辑
  5.     return &GetQuestResponse{QuestID: in.QuestID, Name: "example_quest", Description: "example_description"}, nil
  6. }
  7. func (s *QuestService) CompleteQuest(ctx context.Context, in *CompleteQuestRequest) (*CompleteQuestResponse, error) {
  8.     // 实现完成任务逻辑
  9.     return &CompleteQuestResponse{Success: true, Reward: "example_reward"}, nil
  10. }
复制代码



  • 还会生成路由注册文件,将各个服务注册到服务器。

  1. func main() {
  2.     s := engine.NewServer(
  3.         rpc.NewServer(
  4.             mygame.RegisterUserServiceServer(&UserService{}),
  5.             mygame.RegisterItemServiceServer(&ItemService{}),
  6.             mygame.RegisterQuestServiceServer(&QuestService{}),
  7.         ),
  8.     )
  9.     s.Start()
  10. }
复制代码

对于客户端代码,可以使用以下下令:

  1. goctl rpc client game.proto --zrpc
复制代码

这将生成客户端代码,用于调用长途服务。客户端代码也会按照服务进行区分,方便调用差别的服务方法。

四、总结


通过这个复杂的.proto文件示例,我们展示了如安在 Go Zero 中构建一个功能丰富的游戏服务架构。利用.proto文件界说清晰的服务接口,再结合goctl工具自动生成代码,大大提高了开辟效率和代码的可维护性。无论是在游戏开辟还是其他领域的微服务架构中,这种方式都具有很大的代价。

希望这篇博客文章能够帮助你更好地明白和运用 Go Zero 与.proto文件,为你的项目开辟带来更多的便利和强大的功能。

第一个题目,带rpc和不带rpc有什么区别 第二个题目.api文件和.proto文件可以交换吗

一、带 rpc 和不带 rpc 的区别

在 Protobuf 界说中,使用 “rpc” 关键字界说的是长途过程调用(Remote Procedure Call)方法。


  • 带 “rpc” 的界说:

    • 例如在 .proto 文件中,“service X { rpc MethodName (RequestType) returns (ResponseType); }” 界说了一个可以通过网络长途调用的方法。
    • 它指定了一个服务中的可被长途调用的操纵,明白了输入参数的类型(RequestType)和输出参数的类型(ResponseType)。
    • 通常在分布式系统中,用于差别服务之间的通信,客户端可以通过网络哀求调用这些方法,服务端吸收哀求并执行相应的操纵后返回结果。

  • 不带 “rpc” 的界说:

    • 一样平常来说,不带 “rpc” 的消息界说只是单纯的数据结构界说。
    • 例如 “message SomeType {...}” 界说了一个消息结构体,它可以作为 “rpc” 方法的输入或输出参数类型,但自己不能被直接调用。
    • 这种消息界说主要用于封装数据,方便在差别的服务之间通报结构化的数据。


二、.api 文件和.proto 文件可以交换吗

.api文件和.proto文件一样平常不能直接交换。


  • .proto文件:

    • Protobuf 文件主要用于界说数据结构和长途过程调用服务接口。
    • 它具有明白的语法和规范,特殊实用于高效的序列化和长途过程调用场景。
    • 在 Go Zero 中,可以使用 goctl 等工具根据 .proto 文件生成服务端和客户端代码。

  • .api文件:

    • 没有一个同一的标准格式的 “.api” 文件。在差别的上下文中,.api文件可能有差别的用途和格式。
    • 如果是特定框架或工具自界说的一种 API 形貌文件,它的功能和语法可能与 .proto 文件有很大差别。
    • 纵然它也用于形貌服务接口,其语法、功能和可支持的工具可能与 .proto 文件差别,以是一样平常不能直接交换。


综上所述,带 “rpc” 和不带 “rpc” 在 Protobuf 中有明白的功能区分,而.api文件和.proto文件通常不能交换使用。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

盛世宏图

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表