Hello World ~~~

Fork me on GitHub
lucky528

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
统计
 

 

GRPC使用protocol buffers 作为接口定义语言(IDL)和信息交换格式。

安装GRPC

按照GRPC官方的教程,第一步要安装PROTOBUF的编译器

下载地址:

https://github.com/protocolbuffers/protobuf/releases/tag/v3.17.0

我这里下载了个 windows版本的  protoc-3.17.0-win64.zip

下载完成之后,配置一下环境变量,使得protoc 可以在cmd中运行。

image

配置完成之后验证一下

image

下面安装针对go语言相关的GRPC插件

为了安装顺利,设置一下go语言的国内代理,防止被墙

go env -w GOPROXY=https://goproxy.cn,direct

安装将.proto生成go代码的插件

go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26

由于这个插件并不包含 proto中 service 的部分,需要包含用于生成go-grpc的代码还需要安装下面的工具

在安装完成之后,我们的GOPATH/bin 中就会存在这两个文件

image

实践GRPC

首先新建一个go项目 grpcdemo

目录结构如下:

proto/gen/go

main.go

在proto中新建greeting.proto文件

在greeting.proto中写入:

复制代码
// 使用 version 3版本的protocol buffer
syntax = "proto3";
// 指定 go package 的路径 和需要导入的名字
option go_package="grpcdemo/proto/gen/go;greeting";
//定义性别的枚举类型
enum Gender{
    MALE =0;
    FEMALE =1;
}
// User 
message User{
    int32 User_ID=1;  // 指定第1个字段
    string User_Name=2; // 指定第2个字段
    Gender gender=3;// 指定第3个字段
}
// GreetingTxt
message GreetingTxt {
    int32 Id =1;
    string Content=2;
    // repeated 用于生产切片类型的字段
    repeated User Receives=3;
}
// GetGreetingTxtRequest server method 的请求结构
message GetGreetingTxtRequest {
    int32 Id =1;
}
// GetGreetingTxtRequest server method 的响应结构
message GetGreetingTxtResponse{
    GreetingTxt Txt =1;
}
// Greeter 定义一个 service 用于 client  -server之间的 交互
service Greeter{
    // GetGreetingTxt 定义方法
    rpc GetGreetingTxt ( GetGreetingTxtRequest) returns (GetGreetingTxtResponse);
}
复制代码

在 proto目录中执行CMD

protoc --proto_path=.  --go_out=gen/go --go_opt=paths=source_relative greeting.proto

会在grpcdemo/proto/gen/go 下生成 greeting.pb.go 里边包含了 proto的message go语言的基础代码

然后执行

protoc --proto_path=.  --go-grpc_out=gen/go --go-grpc_opt=paths=source_relative greeting.proto

会在grpcdemo/proto/gen/go 下生成greeting_grpc.pb.go文件,其中包含了 grpc service的代码。

.proto文件生成go代码的工作准备完毕,我们可以编写用于server –client 交互的代码用于测试grpc的 发送和响应。

在grpcdemo下新建文件夹 services,在它下面新建greetor.go 文件 用于在服务端实现 刚刚定义好的 GetGreetingTxt 方法

复制代码
package services

import (
    "context"
    greeting "grpcdemo/proto/gen/go"
)

type Greetor struct {
    greeting.UnimplementedGreeterServer
}

// GetGreetingTxt implement  interface method
func (*Greetor) GetGreetingTxt(context.Context, *greeting.GetGreetingTxtRequest) (*greeting.GetGreetingTxtResponse, error) {
    return &greeting.GetGreetingTxtResponse{
        Txt: &greeting.GreetingTxt{
            Receives: []*greeting.User{
                {
                    User_ID:   1,
                    User_Name: "gopher",
                    Gender:    greeting.Gender_MALE,
                },
                {
                    User_ID:   2,
                    User_Name: "csharp",
                    Gender:    greeting.Gender_FEMALE,
                },
            },
            Content: "hello grpc",
            Id:      1,
        },
    }, nil
}
复制代码

 

其中GetGreetingTxt 是 接口的实现方法,值得注意的地方是 greeting.UnimplementedGreeterServer

这个结构体会自动实现一些未实现的方法,虽然听起来很怪,看一下grpc生成的代码就很好理解了。

func (UnimplementedGreeterServer) GetGreetingTxt(context.Context, *GetGreetingTxtRequest) (*GetGreetingTxtResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method GetGreetingTxt not implemented")
}

相关的proposal ,有兴趣的可以看一下 https://github.com/grpc/grpc-go/issues/3669

既然有了方法的实现,还要加入针对grpc的链接和调用

在 grpcdemo/main.go中写入:

复制代码
package main

import (
    greeting "grpcdemo/proto/gen/go"
    "grpcdemo/services"
    "log"
    "net"

    "google.golang.org/grpc"
)

func main() {
    l, err := net.Listen("tcp", ":8088")
    if err != nil {
        log.Fatalf("listen grpc server error :%v", err)
    }
    server := grpc.NewServer()
    greeting.RegisterGreeterServer(server, &services.Greetor{})
    err = server.Serve(l)
    if err != nil {
        log.Fatalf("server error %v", err)
    }
}
复制代码

这里边监听了 8088端口,下面在 grpcdemo/client中 创建一个用于调用 方法的客户端 main.go

复制代码
connclient, err := grpc.Dial("localhost:8088", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("connection error %v", err)
    }
    defer connclient.Close()
    greetingClient := greeting.NewGreeterClient(connclient)
    resp, err := greetingClient.GetGreetingTxt(context.Background(), &greeting.GetGreetingTxtRequest{
        Id: 1,
    })
    if err != nil {
        log.Fatalf("invoke server grpc error:%v", err)
    }
    log.Printf("response :%v \n", resp)
复制代码

运行服务端和客户端,就能在客户端命令行中看到消息的response打印输出,完成了一次grpc的请求调用。

原文地址

 

posted on   gopher666  阅读(116)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
 
点击右上角即可分享
微信分享提示