go游戏后端开发8:grpc客户端构建

接下来,我们在实现 GRPC 客户端服务发现 的时候,首先需要编写一个 proto 文件。这个 proto 文件是定义服务的基础,只有创建好之后,GRPC 才会自动生成对应的 服务端和客户端代码。我们后续的开发工作,都需要依赖这些自动生成的代码来完成。

在开始之前,我们先来创建一个 proto 文件。以用户注册功能为例,我们将其命名为 userProtocol.proto。创建完成后,我们需要将文件内容拷贝到指定目录。具体来说,我们将其放置在 UZ 下的 PB 目录中。这个目录是我们指定的生成代码的存放位置,同时,生成的 Go 代码的包名(package)也命名为 PB

我们的服务接口要求的参数包括 accountpassword 等。这些参数来源于接口文档中定义的请求参数。接口文档中还规定了返回值,包括一个 token 和一个服务地址(server address)。在注册完成后,我们通常会得到一个用户 ID(uid),然后根据这个用户 ID 生成 token。至于服务地址,为了简单起见,我们暂时直接返回一个固定的地址,后续再逐步实现负载均衡等功能。

在用户服务的实现中,我们只需要返回 uid,以便网关根据这个 uid 生成对应的 token。因此,我们只需要关注这两个关键的参数。

接下来,我们定义一个服务(service)。有了 proto 文件之后,我们需要生成对应的代码。生成代码时,我们可以通过编写一个脚本来简化操作。由于我使用的是 Windows 系统,因此我编写了一个 .bat 脚本。这个脚本本质上是一个命令行工具,用于调用 protoc 命令来生成代码。

在开始之前,大家一定要确保安装了 protoc(Protocol Buffers 的编译器),并且将其配置到系统的 PATH 路径中。配置完成后,我们就可以通过命令行调用 protoc 来生成代码了。

package rpc

import (
	"common/config"
	"common/logs"
	"context"
	"core/discovery"
	"fmt"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/resolver"
	"user/pb"
)

var (
	UserClient pb.UserServiceClient
)

func Init() {
	r := discovery.NewResolver(config.Conf.Etcd)
	resolver.Register(r)
	domain := config.Conf.Domain["user"]
	initClient(r.Scheme(), domain.Name, domain.LoadBalance, &UserClient)

}

func initClient(scheme, name string, loadBalance bool, client interface{}) {
	addr := fmt.Sprintf("%s:///%s", scheme, name)
	opts := []grpc.DialOption{
		grpc.WithTransportCredentials(insecure.NewCredentials())}
	if loadBalance {
		opts = append(opts, grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
	}
	conn, err := grpc.DialContext(context.TODO(), addr, opts...)
	if err != nil {
		logs.Fatal("rpc connect etcd error: %v", err)
	}
	switch c := client.(type) {
	case *pb.UserServiceClient:
		*c = pb.NewUserServiceClient(conn)
	default:
		logs.Fatal("unsupported client type")
	}
}

生成代码时,我们需要指定输出目录,这里是 PB 目录。同时,我们还需要将 GRPC 相关的代码也生成到这个目录中。具体操作是根据 userProtocol.proto 文件来生成对应的代码。生成完成后,我们可以通过运行脚本来完成整个过程。运行完成后,关闭脚本,生成的代码就会出现在指定目录中。

生成的代码中包含了服务端和客户端的相关代码,这些代码是我们后续实现功能的基础。我们需要在这些代码的基础上,实现具体的业务逻辑。

接下来,我们将服务注册到 GRPC Server 中。在注册时,我们需要调用 registerUserServiceServer 方法,将我们实现的服务注册到 GRPC Server 中。注册完成后,我们的服务就可以被客户端调用了。

为了实现服务,我们首先需要创建一个服务类。通常情况下,我们将服务类放在内部目录(internal)中,以避免被其他模块直接引用。这样可以更好地封装我们的业务逻辑。

以用户服务为例,我们创建一个 userService 类,并在其中实现具体的业务逻辑。例如,我们实现一个 CreateAccount 方法,用于处理用户注册的逻辑。在这个方法中,我们需要与数据库进行交互,因此需要引入数据库连接管理器。

在实现业务逻辑时,我们需要注意,我们的服务类需要实现 proto 文件中定义的接口。这意味着我们需要按照接口中定义的方法和参数来实现服务。

实现完成后,我们可以在服务类中打印一些日志信息,以便在调用时能够看到服务是否被正确调用。例如,我们可以在 CreateAccount 方法中打印一条日志,表示注册方法被调用。

接下来,我们需要在网关中调用这个服务。网关需要通过客户端来调用服务。客户端是通过 GRPC 的 PB 文件生成的。我们需要在网关中建立一个 GRPC 客户端,用于连接服务端。

为了建立客户端,我们需要进行初始化操作。这个初始化操作可以放在一个通用的模块中,例如 common 模块,因为其他模块也可能需要使用 GRPC 客户端。在初始化时,我们需要指定服务的地址,这个地址可以通过 ETCD 获取。

在网关中,我们可以通过调用服务端的接口来获取服务地址。然后,我们通过这个地址建立 GRPC 连接。连接成功后,我们就可以通过客户端调用服务端的方法了。

例如,我们可以在网关中调用 CreateAccount 方法,并传递相应的参数。调用成功后,服务端会返回一个 uid,我们根据这个 uid 生成对应的 token,并返回给客户端。

整个流程中,我们需要关注的关键点包括:

  1. proto 文件的编写:定义服务接口和参数。

  2. 代码生成:通过 protoc 工具生成服务端和客户端代码。

  3. 服务注册:将服务注册到 GRPC Server 中。

  4. 业务逻辑实现:在服务类中实现具体的业务逻辑。

  5. 客户端调用:在网关中通过客户端调用服务端的方法。

接下来,我们需要编写一个 ETCD 解析器,用于在 GRPC 连接时从 ETCD 中获取服务地址。这个解析器是整个服务发现机制的核心部分,它确保客户端能够正确地找到服务端的地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值