grpc入门系列之1-Unary模式

gRPC支持四种类型的方法,分别是:

  • Unary模式
  • 客户端流模式
  • 服务端流模式
  • 双向流模式

其中最常见的是Unary模式(即一元模式),我们在本章节仅介绍Unary模式。

Unary模式,也可以称为"一问一答模式",客户端发送一个请求给服务端,服务端返回一个响应,和一次普通的函数调用类似。 示意图如下:

下面我们来实现一个简单的Unary接口。

要通过grpc提供接口,可以分为以下三个步骤:

  • 接口定义(.proto文件)。
  • 生成相关代码。
  • 服务端开发。
  • 客户端开发。

接口定义

我们这里实现一个简单的greet功能,项目目录结构如下:

txt 复制代码
proto 存放proto文件。
pb 存放生成的go文件。
server 服务端代码。
client 客户端代码。
bin 可执行文件。

proto文件定义如下(greet.proto):

proto 复制代码
syntax = "proto3";

package proto;

option go_package = "git.gqnotes.com/guoqiang/grpcexercises/greet/pb";

service GreetService {
  rpc Greet(GreetRequest) returns(GreetResponse) {}
}

message GreetRequest {
  string greeting = 1;
}


message GreetResponse {
  string result = 1;
}

定义Makefile,方便执行相关操作:

makefile 复制代码
tidy:
	go mod tidy

greet-gen:
	 protoc -Igreet/proto/ --go_out=./greet --go_opt=module=git.gqnotes.com/guoqiang/grpcexercises/greet --go-grpc_out=./greet --go-grpc_opt=module=git.gqnotes.com/guoqiang/grpcexercises/greet greet/proto/*.proto

greet-build:
	 go build -o ./greet/bin/server-osx ./greet/server
	 go build -o ./greet/bin/client-osx ./greet/client

.PHONY: tidy greet-gen greet-build

生成相关代码

在项目目录(greet上级目录)下执行如命令:

sh 复制代码
make greet-gen

执行成功,在pb目录下生成相关文件。

服务端开发

在server目录下添加两个文件:

  • main.go,服务入口文件。
  • Greet.go,Greet方法实现。

代码如下:
main.go

go 复制代码
package main

import (
	"git.gqnotes.com/guoqiang/grpcexercises/greet/pb"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
	"log"
	"net"
)

func main() {
	// 实现服务端逻辑,监听5632端口
	lis, err := net.Listen("tcp", ":5632")

	if err != nil {
		log.Fatalf("failed to listen: %v", err)
		return
	}

	s := grpc.NewServer()

	// 注册服务
	pb.RegisterGreetServiceServer(s, &Server{})

	reflection.Register(s)

	log.Println("grpc server start")

	if err = s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
		return
	}
}

type Server struct {
	pb.UnimplementedGreetServiceServer
}

Greet.go ```go package main

import ( "context" "git.gqnotes.com/guoqiang/grpcexercises/greet/pb" "log" "time" )

// Greet greet func (s *Server) Greet(ctx context.Context, req *pb.GreetRequest) (*pb.GreetResponse, error) { log.Printf("Greet function was invoked with %v\n", req)

css 复制代码
result := "Hello " + req.GetGreeting() + ", now time is:" + time.Now().String()

res := &pb.GreetResponse{
	Result: result,
}

return res, nil

}

less 复制代码
</details>

## 客户端开发
在client目录下添加客户端代码,有两个文件:
- main.go,程序入口文件。
- Greet.go,具体方法文件。


文件内容如下:
<details>
  <summary>main.go</summary>

```go
package main

import (
	"git.gqnotes.com/guoqiang/grpcexercises/greet/pb"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"log"
)

func main() {
	conn, err := grpc.Dial(":5632", grpc.WithTransportCredentials(insecure.NewCredentials()))

	if err != nil {
		log.Fatalf("failed to dial: %v", err)
		return
	}

	defer conn.Close()

	// 实例化客户端
	client := pb.NewGreetServiceClient(conn)

	// 调用方法
	Greet(client)
}

Greet.go

go 复制代码
package main

import (
	"context"
	"git.gqnotes.com/guoqiang/grpcexercises/greet/pb"
	"log"
)

func Greet(client pb.GreetServiceClient) {
	response, err := client.Greet(context.Background(), &pb.GreetRequest{
		Greeting: "xiaoming",
	})

	if err != nil {
		log.Fatalf("failed to call Greet: %v", err)
		return
	}

	log.Printf("response:%+v\n", response)
}

执行

在项目目录下执行make tidy,拉取相关库,然后执行 make greet-build,生成可执行文件。 然后在命令行下执行如下命令,启动服务端程序:

bash 复制代码
./greet/bin/server-osx

执行如下命令,测试客户端文件:

bash 复制代码
./greet/bin/client-osx

执行结果如下:

txt 复制代码
2023/12/02 15:02:26 response:result:"Hello xiaoming now time is:2023-12-02 15:02:26.443767 +0800 CST m=+1268.825308543"

代码地址

本文由mdnice多平台发布

相关推荐
Victor3564 小时前
MongoDB(2)MongoDB与传统关系型数据库的主要区别是什么?
后端
JaguarJack4 小时前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端·php·服务端
BingoGo4 小时前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端
Victor3564 小时前
MongoDB(3)什么是文档(Document)?
后端
牛奔6 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
想用offer打牌11 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
KYGALYX12 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了12 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
爬山算法13 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
Moment13 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端