grpc
grpc跨平台微服务框架,但是缺少服务治理的功能,服务发现给出了架子需要自己实现。
go 包下载
go get -u google.golang.org/grpc
proto 工具下载
1、下载 idl 代码生成工具
repo1.maven.org/maven2/com/… protoc 放在环境变量的 path 中
2、下载生成 go 代码插件
go get -u github.com/golang/protobuf/protoc-gen-go
从 GoBin 目录中拷贝出来 protoc-gen-go,放在环境变量 path 中
IDL
IDL 语法,详细的请查看 Protobuf3 语言指南
例子
代码脚手架
1、编写 book.proto 文件
syntax = "proto3";
// 请求书详情的参数结构 book_id 32 位整形
message BookInfoParams {
int32 book_id = 1;
}
// 书详情信息的结构 book_name 字符串类型
message BookInfo {
int32 book_id = 1;
string book_name = 2;
}
// 请求书列表的参数结构 page、limit 32 位整形
message BookListParams {
int32 page = 1;
int32 limit = 2;
}
// 书列表的结构 BookInfo 结构数组
message BookList {
repeated BookInfo book_list = 1;
}
// 定义 获取书详情 和 书列表服务 入参出参分别为上面所定义的结构
service BookService {
rpc GetBookInfo (BookInfoParams) returns (BookInfo) {}
rpc GetBookList (BookListParams) returns (BookList) {}}
2、生成对应语言 proto 代码
protoc --go_out=plugins=grpc:. book.proto
当前文件夹下会生成 book.pb.go 文件,也可以生成其它语言的代码
protoc --php_out=. book.proto
3、解决小冲突 gol 的 grpc 插件指定 context 路径 contextPkgPath = “golang.org/x/net/conte…"可能会与我们代码中的 context 冲突 把 book.proto 中 import"golang.org/x/net/conte…” 更改为 “context”
服务端代码
package main
import (
"grpc-test/pb"
"net" "context" "google.golang.org/grpc"
)
/**
创建 BookServer 结构 实现 BookServiceServer 接口
type BookServiceServer interface {GetBookInfo(context.Context, *BookInfoParams) (*BookInfo, error)
GetBookList(context.Context, *BookListParams) (*BookList, error)
}
*/
type BookServer struct {}
func (s *BookServer) GetBookInfo(ctx context.Context, in *book.BookInfoParams) (*book.BookInfo, error) {
// 请求详情时返回 书籍信息
b := new(book.BookInfo)
b.BookId = in.BookId
b.BookName = "21 天精通 php"
return b,nil
}
func (s *BookServer) GetBookList(ctx context.Context, in *book.BookListParams) (*book.BookList, error) {
// 请求列表时返回 书籍列表
bl := new(book.BookList)
bl.BookList = append(bl.BookList, &book.BookInfo{BookId:1,BookName:"21 天精通 php"})
bl.BookList = append(bl.BookList, &book.BookInfo{BookId:2,BookName:"21 天精通 java"})
return bl,nil
}
func main() {
serviceAddress := ":50052"
bookServer := new(BookServer)
// 创建 tcp 监听
ls, _ := net.Listen("tcp", serviceAddress)
// 创建 grpc 服务
gs := grpc.NewServer()
// 注册 bookServer
book.RegisterBookServiceServer(gs, bookServer)
// 启动服务
gs.Serve(ls)
}
客户端代码
package main
import (
"fmt"
"grpc-test/pb" "google.golang.org/grpc"
"context"
)
func main() {
serviceAddress := "127.0.0.1:50052"
conn, err := grpc.Dial(serviceAddress, grpc.WithInsecure())
if err != nil {
panic("connect error")
}
defer conn.Close()
bookClient := book.NewBookServiceClient(conn)
bi,_:=bookClient.GetBookInfo(context.Background(),&book.BookInfoParams{BookId:1})
fmt.Println("获取书籍详情")
fmt.Println("bookId: 1", "=>", "bookName:", bi.BookName)
bl,_ := bookClient.GetBookList(context.Background(), &book.BookListParams{Page:1, Limit:10})
fmt.Println("获取书籍列表")
for _,b := range bl.BookList {
fmt.Println("bookId:", b.BookId, "=>", "bookName:", b.BookName)
}
}
启动测试
启动 server,client
GOROOT=D:\Go #gosetup
GOPATH=D:\go\gopath #gosetup
D:\Go\bin\go.exe build -i -o C:\Users\Administrator\AppData\Local\Temp\___17110go_build_main_go.exe D:/go/gopath/src/grpc-test/client/main.go #gosetup
D:\软件\GoLand\bin\runnerw.exe C:\Users\Administrator\AppData\Local\Temp\___17110go_build_main_go.exe #gosetup
获取书籍详情
bookId: 1 => bookName: 21天精通php
获取书籍列表
bookId: 1 => bookName: 21天精通php
bookId: 2 => bookName: 21天精通java
Process finished with exit code 0