Golang gRPC 和 gRPC-gateway 结合使用

一、安装

go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
go get -u github.com/golang/protobuf/protoc-gen-go

二、proto 文件

syntax = "proto3";
package gateway;

import "google/api/annotations.proto";

message StringMessage {
    string value = 1;
}

service Gateway {
   rpc Echo(StringMessage) returns (StringMessage) {
       option (google.api.http) = {
           post: "/v1/example/echo"
           body: "*"
       };
   }
}
View Code

执行 protoc 编译,生成两个 go 文件,一个是提供 service 的,一个是 gateway 的:

protoc --proto_path=../ -I/usr/local/include -I. -I/home/go-plugin/src -I/home/go-plugin/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --go_out=plugins=grpc:. gateway.proto
protoc --proto_path=../ -I/usr/local/include -I. -I/home/go-plugin/src -I/home/go-plugin/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --grpc-gateway_out=logtostderr=true:. gateway.proto

 生成的文件如下:

第一个是 service,第二个是 gateway

三、编写 go 程序

1、service

package main

import (
    "log"
    "net"

    pb "test_grpc/gateway"
    "google.golang.org/grpc"
    "golang.org/x/net/context"
)

const (
    PORT = ":9192"
)

type server struct {}

func (s *server) Echo(ctx context.Context, in *pb.StringMessage) (*pb.StringMessage, error) {
    log.Println("request: ", in.Value)
    return &pb.StringMessage{Value: "Hello " + in.Value}, nil
}

func main() {
    lis, err := net.Listen("tcp", PORT)

    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }

    s := grpc.NewServer()
    pb.RegisterGatewayServer(s, &server{})
    log.Println("rpc服务已经开启")
    s.Serve(lis)
}
View Code

2、gateway

package main

import (
    "flag"
    "net/http"
    "log"

    "github.com/golang/glog"
    "golang.org/x/net/context"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "google.golang.org/grpc"
    gw "test_grpc/gateway"
)

var (
    echoEndpoint = flag.String("echo_endpoint", "localhost:9192", "endpoint of Gateway")
)

func run() error {
    ctx := context.Background()
    ctx, cancel := context.WithCancel(ctx)
    defer cancel()

    mux := runtime.NewServeMux()
    opts := []grpc.DialOption{grpc.WithInsecure()}
    err := gw.RegisterGatewayHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts)
    if err != nil {
        return err
    }

    log.Println("服务开启")
    return http.ListenAndServe(":8080", mux)
}

func main() {
    flag.Parse()
    defer glog.Flush()

    if err := run(); err != nil {
        glog.Fatal(err)
    }
}
View Code

四、开启服务

先开启 service,再开启 gateway

 

转载于:https://www.cnblogs.com/linguoguo/p/10148467.html

在Go语言中,GRPC Gateway是一个工具,它允许你将现有的gRPC服务转换成HTTP API,而无需修改服务端代码。下面是一个简单的gRPC到HTTP的示例,我们将创建一个简单的`HelloService` gRPC服务,并通过Gateway将其暴露为RESTful API。 首先,安装必要的依赖: ```sh go get google.golang.org/grpc go get github.com/grpc-ecosystem/grpc-gateway/v2 ``` 然后,假设我们有一个名为`hello.proto`的协议定义文件,内容如下: ```protobuf syntax = "proto3"; package hello; service Hello { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; } ``` 接下来,生成服务器客户端代码: ```sh protoc -I=$GOPATH/src -I=$SRC_DIR -o $GOPATH/src/hello/hello.pb.go $SRC_DIR/hello.proto protoc -I=$GOPATH/src -I=$SRC_DIR --grpc-gateway_out=logtostderr=true:. $SRC_DIR/hello.proto ``` 创建一个简单的`server/main.go`: ```go package main import ( "context" "fmt" "log" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" _ "github.com/grpc-ecosystem/grpc-gateway/v2/examples/helloworld" "golang.org/x/net/context" "hello/hellopb" ) func main() { lis, err := grpc.Listen("0.0.0.0:50051", nil) if err != nil { log.Fatalf("failed to listen: %v", err) } srv := grpc.NewServer() hellopb.RegisterHelloServer(srv, &HelloServiceImpl{}) runtime.ServeGRPC(mux, srv) fmt.Println("Starting server on port 50051") if err := lis.Serve(); err != nil { log.Fatal(err) } } type HelloServiceImpl struct{} func (h *HelloServiceImpl) SayHello(ctx context.Context, req *hellopb.HelloRequest) (*hellopb.HelloReply, error) { return &hellopb.HelloReply{Message: fmt.Sprintf("Hello, %s!", req.Name)}, nil } ``` 最后,在`gateway/gateway.yaml`里配置路由: ```yaml # gateway.yaml openapi: 3.0.2 info: title: Simple Greeting Service version: 1.0.0 servers: - url: http://localhost:8000/ paths: /hello: post: summary: Greet a user operationId: SayHello requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: The user's name responses: '200': description: A successful response with the greeting. content: application/json: schema: type: object properties: message: type: string ``` 运行`server``gateway`: ```sh go run server/main.go go run gateway/gateway_main.go ``` 现在你可以访问`http://localhost:8000/hello`并发送POST请求,数据包含`name`字段,服务器会返回一个问候消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值