快速开始
安装 gateway 。文档地址:https://grpc-ecosystem.github.io/grpc-gateway/
go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
下载三个文件
https://github.com/googleapis/googleapis/blob/master/google/api/annotations.proto https://github.com/googleapis/googleapis/blob/master/google/api/http.proto https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto
在pb下创建对应的目录。
- build.bat文件中,添加gateway:
—grpc-gateway_out . —grpc-gateway_opt paths=source_relative
完整的:
protoc —plugin=protoc-gen-go=%GOBIN%/protoc-gen-go.exe —plugin=protoc-gen-go-grpc=%GOBIN%/protoc-gen-go-grpc.exe —grpc-gateway_out . —grpc-gateway_opt paths=source_relative —go_out=. —go_opt=paths=source_relative —go-grpc_out=. —go-grpc_opt=paths=source_relative ./person/person.proto
如果说没有找到 grpc-gateway插件:
先看下bin目录下有没有,没有的话需要下载 他是一个exe文件:
go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
如果有的话,就手动写上位置
protoc --plugin=protoc-gen-go=%GOBIN%/protoc-gen-go.exe --plugin=protoc-gen-grpc-gateway=%GOBIN%/protoc-gen-grpc-gateway.exe --plugin=protoc-gen-go-grpc=%GOBIN%/protoc-gen-go-grpc.exe --grpc-gateway_out . --grpc-gateway_opt paths=source_relative --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative ./person/person.proto
使用能获取到GOBIN变量的窗口执行。
- 成功后的:
使其grpc也能有http接口
在proto文件中,将申明的Search方法绑定到一个http接口。
syntax = "proto3";
package person;
option go_package = "./;person";
import "google/api/annotations.proto";
message PersonReq {
string name = 1;
int32 age = 2;
}
message PersonRes {
string name = 1;
int32 age = 2;
}
service SearchService {
rpc Search(PersonReq) returns (PersonRes){
option (google.api.http)={
post:"/api/person",
body:"*"
};
};//传统的即刻响应
}
package main
import (
"context"
"fmt"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"grpc_test_stream/pb/person"
"net"
"net/http"
"sync"
)
type Sever struct {
person.UnimplementedSearchServiceServer
}
func (Sever) Search(ctx context.Context, req *person.PersonReq) (*person.PersonRes, error) {
name := req.GetName()
p := new(person.PersonRes)
p.Name = "我收到了来自" + name + "的请求"
fmt.Println(req)
return p, nil
}
func main() {
wg := new(sync.WaitGroup)
wg.Add(2)
go registerGateway(wg)
go registeGrpc(wg)
wg.Wait()
fmt.Println("服务端启动成功")
}
func registerGateway(wg *sync.WaitGroup) {
dialContext, err2 := grpc.DialContext(
context.Background(),
"127.0.0.1:8888",
grpc.WithBlock(),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err2 != nil {
fmt.Println(err2)
}
//这个在我本地有两个版本,不同版本的包删除掉吧
mux := runtime.NewServeMux() //这是grpc里面的runtime
http_server := &http.Server{
Handler: mux,
Addr: ":8090", //http对外的端口号
}
err2 = person.RegisterSearchServiceHandler(context.Background(), mux, dialContext)
if err2 != nil {
fmt.Println(err2)
}
http_server.ListenAndServe()
wg.Done()
}
func registeGrpc(wg *sync.WaitGroup) {
listener, err := net.Listen("tcp", ":8888")
if err != nil {
fmt.Println(err)
fmt.Println("监听失败1")
}
grpc_server := grpc.NewServer()
person.RegisterSearchServiceServer(grpc_server, &Sever{})
err = grpc_server.Serve(listener)
if err != nil {
fmt.Println(err)
fmt.Println("监听失败2")
}
wg.Done()
}