1

I'm sure all the services are working properly.

I have the code below:

This snippet is used for registering two endpoints.

func RegisterEndpoints(ctx context.Context, c *utils.AppConfig, r resolver.Builder) (http.Handler, error) {
    var err error
    mux := runtime.NewServeMux()
    dialOpts := []grpc.DialOption{grpc.WithBalancerName("round_robin"), grpc.WithInsecure()}

    err = protos.RegisterUserCenterHandlerFromEndpoint(ctx, mux, r.Scheme()+"://author/user-center", dialOpts)
    if err != nil {
        return nil, err
    }

    err = protos.RegisterSsoHandlerFromEndpoint(ctx, mux, r.Scheme()+"://author/sso", dialOpts)
    if err != nil {
        return nil, err
    }

    return mux, nil
}

And in my main.go,I build a resolver to resolve name to address, then register the two endpoints and listen on port 8080.

func run() error {
    c := utils.GetAppConfig()

    ctx := context.Background()
    ctx, cancel := context.WithCancel(ctx)
    defer cancel()

    r := localresolver.NewResolver(fmt.Sprintf("%s:%d", c.Registry.Host, c.Registry.Port))
    resolver.Register(r)

    mux := http.NewServeMux()

    // Register endpoints here
    gw, err := routes.RegisterEndpoints(ctx, c, r)
    if err != nil {
        return err
    }
    mux.Handle("/", gw)
    fmt.Println("Listening localhost:8080...")
    return http.ListenAndServe(fmt.Sprintf("%s:%d", c.Gateway.Host, c.Gateway.Port), mux)
}

func main() {
    defer glog.Flush()

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

But after I ran go run main.go, I found that only the last service I registered can be accessed, that is sso service (the err = protos.RegisterSsoHandlerFromEndpoint(ctx, mux, r.Scheme()+"://author/sso", dialOpts) line).

Can anyone show me an example of the correct way to register multiple endpoints via grpc-gateway? (make all the services registered with grpc-gateway can successfully be visited)


[2020-01-31] Need more help, now my code is like below:

the latest code

Other code are same as before.

Additional, this is the result which name resolver shows:

name resolver resolves the addresses

Rex Tsao
  • 65
  • 1
  • 13

2 Answers2

0

There is no need to pass the ServeMux (gw) to mux var as handler, you can just ListenAndServe to the returned gw variable.

    // Register endpoints here
    gw, err := routes.RegisterEndpoints(ctx, c, r)
    if err != nil {
        return err
    }
    fmt.Println("Listening localhost:8080...")
    return http.ListenAndServe(fmt.Sprintf("%s:%d", c.Gateway.Host, c.Gateway.Port), gw)

and in RegisterEndpoints function, the endpoint parameter should be your host:port, the api endpoint should be provided in the google api annotation in the proto file.

    err = protos.RegisterUserCenterHandlerFromEndpoint(ctx, mux, fmt.Sprintf("%s:%d", c.Gateway.Host, c.Gateway.Port), dialOpts)
    if err != nil {
        return nil, err
    }

    err = protos.RegisterSsoHandlerFromEndpoint(ctx, mux, fmt.Sprintf("%s:%d", c.Gateway.Host, c.Gateway.Port), dialOpts)
    if err != nil {
        return nil, err
    }
Andy
  • 449
  • 5
  • 13
  • Appreciate your answer, but follow your advice, it still can't work. In my case, I use `etcd` as the registry, so the two service `user-center` and `sso` have different `host:port` pairs, so I use `r` as the resolver to tell gRPC to resolve the address. After I launched the `grpc-gateway` service, both addresses of them are discovered, but still only the last registered one can be accessed. Hope more help. – Rex Tsao Jan 31 '20 at 05:50
  • I've updated this question to show more detail, looking forward to your reply. – Rex Tsao Jan 31 '20 at 06:04
0

I appended grpc.WithBlock() to grpc.DialOption, then all services can be accessed via grpc-gateway now.

Like below:

dialOpts := []grpc.DialOption{grpc.WithBalancerName("round_robin"), grpc.WithInsecure(), grpc.WithBlock()}
Rex Tsao
  • 65
  • 1
  • 13