请注意,本文编写于 1180 天前,最后修改于 950 天前,其中某些信息可能已经过时。
本人设备环境: windows 10 , Goland , GoSDK:1.7 ,protoc插件 ,grpc库。
protoc编译插件库当前使用列表:
文件下载库链接
https://wwa.lanzoui.com/iwMzItmrmhc
文件配置步骤:在系统变量里面寻找到path->选择新建->选择浏览目录->将protoc文件夹路径+/bin 这个执行文件就可以了。
当配置完毕后需要重启cmd才能成功,如果是goland里面的终端则是重启cgoland
新建protoc文件,
解析:
syntax="proto3"
确定协议头版本
package main
申明包名
option go_package="/protoc"
设定文件输出目录,这个极为重要
server FileUpload {
rpc upload (stream Chinl ) returns (UploadStar){}
}
注册服务upload ,可以通过流(stream)来进行传输文件,实现文件上传功能
前置变量服务:
enum UploadSteam {
Unknown=0;
ok=1;
Failed=2;
}
//利用bytes用户传输文件,配合grpc的流服务
message Chinl{
bytes Content=1;
}
message UploadStar{
string Message=1;
UploadSteam code=2;
}
这是实现流服务需要注册申明的东西:
enum关键字用于枚举定义类型,可以增加自定义类型供给其他函数调用。
message注册一个消息类型。
server 定义接口服务
rpc 定义一个rpc服务,同时可以使用option定义类型,如http类型。
须知原始的rpc服务就是tcp服务。
定义的属性后面的数字必须按照顺序写出,如string Message=1; 必须以1开头,部分可以0 ,然后一直顺序走
这里我们在看一下经过编译后的文件信息,这里摘重点看
如rpc upload 变成了:
func (c *fileUploadClient) Upload(ctx context.Context, opts ...grpc.CallOption) (FileUpload_UploadClient, error) {
stream, err := c.cc.NewStream(ctx, &_FileUpload_serviceDesc.Streams[0], "/main.FileUpload/upload", opts...)
if err != nil {
return nil, err
}
x := &fileUploadUploadClient{stream}
return x, nil
}
这个需要联系文件来看。
Chinl则变成了:
type Chinl struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Content []byte `protobuf:"bytes,1,opt,name=Content,proto3" json:"Content,omitempty"`
}
建议大家可以看看生成的pd.go文件里的代码,很有意义。
调用grpc服务的部分代码:
package main
import (
pd "./protoc"
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
"net"
)
//将proto文件转成pd.go的方式 protoc -I . --go_out=plugins=grpc:. set.proto 必须要进入文件目录才能用这个,否则set.proto 需要加上路径
/*
go_out 指定go语言形式
set.proto指定输入的文件地址
这是同一目录下的生成方式,因为proto指定了输出文件目录,所以才会和当前文件不在一个目录
(set.pd.go 文件)
*/
// ProdenServer 定义约定的接口
type ProdenServer struct{}
// ProdenAdd 添加server服务
var ProdenAdd = ProdenServer{}
const (
Address = "localhost:2349" //接口地址
)
// Add 定义函数体方法,Grodens是proto里面的请求结构,Gou则是响应结构
func (Pro ProdenServer) Add(context context.Context, p *pd.Grodens) (*pd.Gou, error) {
res := new(pd.Gou)
res.Mess = fmt.Sprintf(p.Name)
return res, nil
}
func main() {
fmt.Println("服务开启:")
//prc就是tcp协议
listen, err := net.Listen("tcp", Address)
if err != nil {
panic(err)
}
//实例化接口
st := grpc.NewServer()
//注册接口
pd.RegisterProdenServer(st, ProdenAdd)
grpclog.Info("list tcp in:", Address)
err = st.Serve(listen)
if err != nil {
grpclog.Error(err)
}
}
大致就是这些,入了门以后都会很好写,经验很重要。