快速开始

  1. 安装 gateway 。文档地址:https://grpc-ecosystem.github.io/grpc-gateway/

    go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway

  2. 下载三个文件

    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下创建对应的目录。
image.png

  1. 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
如果有的话,就手动写上位置

  1. 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变量的窗口执行。

  1. 成功后的:

image.png

使其grpc也能有http接口

在proto文件中,将申明的Search方法绑定到一个http接口。

  1. syntax = "proto3";
  2. package person;
  3. option go_package = "./;person";
  4. import "google/api/annotations.proto";
  5. message PersonReq {
  6. string name = 1;
  7. int32 age = 2;
  8. }
  9. message PersonRes {
  10. string name = 1;
  11. int32 age = 2;
  12. }
  13. service SearchService {
  14. rpc Search(PersonReq) returns (PersonRes){
  15. option (google.api.http)={
  16. post:"/api/person",
  17. body:"*"
  18. };
  19. };//传统的即刻响应
  20. }
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
  6. "google.golang.org/grpc"
  7. "google.golang.org/grpc/credentials/insecure"
  8. "grpc_test_stream/pb/person"
  9. "net"
  10. "net/http"
  11. "sync"
  12. )
  13. type Sever struct {
  14. person.UnimplementedSearchServiceServer
  15. }
  16. func (Sever) Search(ctx context.Context, req *person.PersonReq) (*person.PersonRes, error) {
  17. name := req.GetName()
  18. p := new(person.PersonRes)
  19. p.Name = "我收到了来自" + name + "的请求"
  20. fmt.Println(req)
  21. return p, nil
  22. }
  23. func main() {
  24. wg := new(sync.WaitGroup)
  25. wg.Add(2)
  26. go registerGateway(wg)
  27. go registeGrpc(wg)
  28. wg.Wait()
  29. fmt.Println("服务端启动成功")
  30. }
  31. func registerGateway(wg *sync.WaitGroup) {
  32. dialContext, err2 := grpc.DialContext(
  33. context.Background(),
  34. "127.0.0.1:8888",
  35. grpc.WithBlock(),
  36. grpc.WithTransportCredentials(insecure.NewCredentials()),
  37. )
  38. if err2 != nil {
  39. fmt.Println(err2)
  40. }
  41. //这个在我本地有两个版本,不同版本的包删除掉吧
  42. mux := runtime.NewServeMux() //这是grpc里面的runtime
  43. http_server := &http.Server{
  44. Handler: mux,
  45. Addr: ":8090", //http对外的端口号
  46. }
  47. err2 = person.RegisterSearchServiceHandler(context.Background(), mux, dialContext)
  48. if err2 != nil {
  49. fmt.Println(err2)
  50. }
  51. http_server.ListenAndServe()
  52. wg.Done()
  53. }
  54. func registeGrpc(wg *sync.WaitGroup) {
  55. listener, err := net.Listen("tcp", ":8888")
  56. if err != nil {
  57. fmt.Println(err)
  58. fmt.Println("监听失败1")
  59. }
  60. grpc_server := grpc.NewServer()
  61. person.RegisterSearchServiceServer(grpc_server, &Sever{})
  62. err = grpc_server.Serve(listener)
  63. if err != nil {
  64. fmt.Println(err)
  65. fmt.Println("监听失败2")
  66. }
  67. wg.Done()
  68. }

image.png