猿问

gRPC GO 单一通用服务处理程序

我使用protoreflect编写了 http-to-gRPC-gateway。但是我没有看到任何简单的选项来做相反的事情 - gRPC-to-HTTP-gateway。其中一个想法是将 GRPC 暴露给外部,但使用自定义网关通过 MessageQ 调用内部微服务以避免负载平衡、发现服务,并且可以将 GRPC 流式转换为持久或使用反射来调用方法而不是使用生成的服务器存根


以下是我到目前为止得到的


func main() {

    lis, err := net.Listen("tcp", ":9091")

    grpcServer := grpc.NewServer(grpc.UnknownServiceHandler(GenericHandler))

    //pb.RegisterGreeterServer(grpcServer, &TestService{})

    grpcServer.Serve(lis)

}


func GenericHandler(srv interface{}, stream grpc.ServerStream) error {

    fullMethodName, ok := grpc.MethodFromServerStream(stream)

    log.Printf("Method: %v, %v\n", fullMethodName, ok)

    //how to get protobuf payload from stream

    //Response:=Invoke Method via Reflection or http or MessageQueue - passing either the raw protocal buffer or as json

    //how to return Response

    return nil

}

我看到实现这一点的唯一方法是理解并重新实现实际的处理程序processUnaryRPC


慕斯709654
浏览 102回答 1
1回答

叮当猫咪

得到它的工作,感谢protoreflect没有错误处理的工作样本//Parse protofile, create grpc.ServiceDesc, registerfunc (s *GRPCService) LoadSpec(protoFileName string) {    p := protoparse.Parser{}    fdlist, _ := p.ParseFiles(protoFileName)    for _, fd := range fdlist {        for _, rsd := range fd.GetServices() {            s.sdMap[rsd.GetName()] = rsd            gsd := grpc.ServiceDesc{ServiceName: rsd.GetName(), HandlerType: (*interface{})(nil)}            for _, m := range rsd.GetMethods() {                gsd.Methods = append(gsd.Methods, grpc.MethodDesc{MethodName: m.GetName(), Handler: s.Handler})            }            s.grpcServer.RegisterService(&gsd, s)        }    }}func (s *GRPCService) Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {    stream := grpc.ServerTransportStreamFromContext(ctx)    arr := strings.Split(stream.Method(), "/")    serviceName := arr[1]    methodName := arr[2]    service := s.sdMap[serviceName]    method := service.FindMethodByName(methodName)    input := dynamic.NewMessage(method.GetInputType())    dec(input)    jsonInput, err := input.MarshalJSON()    log.Printf("Input:%s Err:%v \n", jsonInput, err)    //jsonOutput:=invokeServiceViaReflectionOrHttp(jsonInput)    jsonOutput := `{"message":"response"}`    output := dynamic.NewMessage(method.GetOutputType())    output.UnmarshalJSON([]byte(jsonOutput))    return output, nil}
随时随地看视频慕课网APP

相关分类

Go
我要回答