「gRPC」 Gateway的实现

Golang
589
0
0
2022-09-12
标签   gRPC
gRPC Gateway的实现相应的客户端和服务端代码就已经为我们生成了
我们只需要实现服务端的接口:
// TripServiceServer is the server API for TripService service.
type TripServiceServer interface {
GetTrip(context.Context, *GetTripRequest) (*GetTripResponse, error)
}
接口的实现:
import (
"context"
trippb "coolcar/proto/gen/go"
)
//type TripServiceServer interface {
// GetTrip(context.Context, *GetTripRequest) (*GetTripResponse, error)
// }
type Service struct{}
func (*Service) GetTrip(con context.Context, req *trippb.GetTripRequest) (*trippb.GetTripResponse, error) {
return &trippb.GetTripResponse{
//客户请求什么Id,服务端返回什么Id
Id: req.Id,
Trip: &trippb.Trip{
Statar: "北京"
End: "上海",
DurationSec: 3600,
FeeCent: 1000,
StatarPos: &trippb.Location{
Latitude: 30,
Longitude: 120,
},
EndPos: &trippb.Location{
Latitude: 40,
Longitude: 125,
},
PathLocations: []*trippb.Location{
{
Latitude: 34,
Longitude: 123,
},
{
Latitude: 38,
Longitude: 124,
},
},
Status: trippb.TripStatus_FINISHED,
},
}, nil
}
现在我们来实现获取行程的整个过程:
编写service端和gateway
package main
import (
"context"
trippb "coolcar/proto/gen/go"
trip "coolcar/tripservice"
"fmt"
"log"
"net"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"google.golang.org/grpc"
)
//gateway的实现
func startGRPCGatway() {
c := context.Background() //生成没具体内容的上下文
c, cancel := context.WithCancel(c) //该方法将具有cancel的能力
defer cancel()
//runtime.WithMarshalerOption()将Status: trippb.TripStatus_FINISHED,改为status:3
mux := runtime.NewServeMux(runtime.WithMarshalerOption(
runtime.MIMEWildcard, &runtime.JSONPb{
EnumsAsInts: true, //status
OrigName: true, //命名
},
))
err := trippb.RegisterTripServiceHandlerFromEndpoint(
c, //通过context去连接, 注册在runtime.NewServeMux()上面
mux,
":8081", //连接内部grpc服务端口
[]grpc.DialOption{grpc.WithInsecure()}, //grpc.WithInsecure()连接方式tcp明文,即不做安全处理
)
if err != nil {
log.Fatalf("断开连接: %v", err)
}
//对外暴露http端口
err = http.ListenAndServe(":8080", mux)
if err != nil {
log.Fatalf("连接失败: %v", err)
}
}
//service 端
func main() {
fmt.Println("监听开始")
go startGRPCGatway()
list, err := net.Listen("tcp", ":8081")
if err != nil {
log.Fatalf("监听失败: %v", err)
}
s := grpc.NewServer() //NewServer 创建一个未注册服务且尚未开始接受请求的 gRPC 服务器。
trippb.RegisterTripServiceServer(s, &trip.Service{})
fmt.Println("监听结束")
fmt.Println(list)
log.Fatal(s.Serve(list)) //s.Serve()方法不会退出
}
编写客户端:
  1. 这里也可以通过grpc进行拨号:
package main
import (
"context"
trippb "coolcar/proto/gen/go"
"fmt"
"log"
"google.golang.org/grpc"
)
func main() {
//连接gateway
con, err := grpc.Dial("localhost:8080")
if err != nil {
log.Fatalf("连接失败: %v", err)
}
tsClient := trippb.NewTripServiceClient(con)
res, err := tsClient.GetTrip(context.Background(), &trippb.GetTripRequest{
Id: "trips01",
})
if err != nil {
log.Fatalf("未获取到trips: %v", err)
}
fmt.Println(res)
}
  1. 通过浏览器:http://localhost:8080/trip?Id=trips01
这样整个流程就完了
返回结果:
id:"trips01" trip:{statar:"北京" statar_pos:{latitude:30 longitude:120} path_locations:{latitude:34 longitude:123} path_locations:{latitude:38 longitude:124} end:"上海" end_pos:{latitude:40 longitude:125} duration_sec:3600 fee_cent:1000 status:FINISHED}