Day29-Go gRPC(下)

前言

在上一篇,我们介绍了 gRPC 以及建例 proto 档,今天要来介绍如何使用 gRPC 来建立一套 Server,以及在 Client 端如何去呼叫 Server 端。

gRPC Server

先带来如何建立一个 Server 端,一样先建立好 proto 档,可以参考上一篇:

syntax = "proto3";
 
option go_package = ".;student";
 
package student;
 
service StudentServer { 
   rpc GetStudentData (GetStudentDataReq) returns (GetStudentDataRes) {}
}
 
message GetStudentDataReq { 
   int64  student_id = 1;
   string class = 2;
}
 
message GetStudentDataRes { 
   string student_name = 1;
   int64 student_heigh = 2;
   int64 student_weight = 3;
}

我们要起的服务,包括一只 GetStudentData API,接着就要建立 main function,将服务起起来:

package main

import (
	"context"
	"fmt"
	"net"
	"os"
	"os/signal"
	"syscall"

	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"

	student "student/pb"
)

type studentServer struct {
}

func main() {
	var (
		err              error
		shutdownObserver = make(chan os.Signal, 1)
	)
	// 设定要监听的 port
	lis, err := net.Listen("tcp", ":3010")
	if err != nil {
		panic(err)
	}

	// 使用 gRPC 的 NewServer meethod 来建立 gRPC Server
	grpcServer := grpc.NewServer()
	sv := &studentServer{}
	student.RegisterStudentServerServer(grpcServer, sv)
	// 在 gRPC 服务器上注册反射服务。
	reflection.Register(grpcServer)

	go func(gs *grpc.Server, c chan<- os.Signal) {
		err := gs.Serve(lis)

		if err != nil {
			shutdownObserver <- syscall.SIGINT
		}
	}(grpcServer, shutdownObserver)

	signal.Notify(shutdownObserver, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)

	//阻塞直到有信号传入
	s := <-shutdownObserver
	fmt.Println(`Receive signal:`, s)

	// 优雅停止GRPC服务
	grpcServer.GracefulStop()
}

func (s *studentServer) GetStudentData(ctx context.Context, in *student.GetStudentDataReq) (r *student.GetStudentDataRes, err error) {
	r = &student.GetStudentDataRes{
		StudentName:   "JC",
		StudentHeigh:  178,
		StudentWeight: 70,
	}

	return r, err
}

如此一来,就可以起动这个 Server!

gRPC Client

在 Client 端,要呼叫服务端,作法很简单,直接看程序码:

package main

import (
	"context"
	"fmt"
	"log"

	"google.golang.org/grpc"

	"student/pb"
)

var client student.StudentServerClient

func main() {

	// 建立连线
	conn, err := grpc.Dial("localhost:3010", grpc.WithInsecure())
	if err != nil {
		fmt.Println("连线失败:", err)
	}

	// 最後关闭练线
	defer conn.Close()

	// 用 proto 提供的 NewStudentServerClient,来建立 client
	client = student.NewStudentServerClient(conn)

	GetStudent(1, "A")
}

func GetStudent(studentId int64, class string) {
	res, err := client.GetStudentData(context.Background(),
		&student.GetStudentDataReq{
			StudentId: studentId,
			Class:     class,
		})
	if err != nil {
		log.Fatalf("GetStudentData error: %v", err)
	}
	fmt.Println(res) //执行结果
}

这样将可以建立 Client 端连线了,使用 Server 端提供的服务

结语

今天带来如何在 Go 语言中使用 gRPC,建出一套 Server 和 Client,使用起来不会太过复杂,如果你是想以 Go 语言来开发网站,那 gRPC 是你必须学的一大课题,点对点的即时通讯,使得他非常适合於微服务,会带来非常高的效率。
感谢各位读者今天的阅读,希望对你有帮助!


<<:  食谱搜寻系统demo

>>:  【第二三天 - Flutter iBeacon 官方范例讲解(上)】

Day 1 前言 - 我是谁、我在哪里、我要做什麽

各位同学好,这是我第一次参加铁人赛。 同时感谢团长阿瑜邀请我参加。 我是 JohnTing,一个失业...

Day25 - 补充 Container 和 Hashing

大家好,我是长风青云。今天是铁人赛的第二十五天。 突然发现我有些东西没说,而Hash这个我也忘记说,...

[Day06] 第六章- 开发环境安装(xampp,vscode,composer)

目标 安装环境 勘误修正及补充 1. 前言 到目前为止 已经把永丰的api参数以及相关制作流程做完了...

Day06:爸爸这麽做都是为你好

当我们在定义类别时,有三种东西可以定义,属性(field)、建构子(constructor)、方法(...

[Day6] 注册API – model之AbstractUser

各位夥伴们大家好,今天是我们进入API阶段的第一天,在撰写API的逻辑之前,我们需要先到user\m...