Service Multiplexing

Sometimes we need to start a server running multiple services in the same process, sharing the same port.

gRPC

  1. Define new service in .proto file
+message MeowRequest {
+}

+message MeowResponse {
+  string message = 1;
+}

+service CatService {
+  rpc meow (MeowRequest) returns (MeowResponse) {}
+}
  1. Modify service.yaml, add new APIs
config:
-  grpc_service_name: TestService
+  grpc_service_name: TestService,CatService
urlmapping:
+ - GET /cat/meow CatService Meow
  1. Generate new code
$ turbo generate package/path/to/yourservice -r grpc -I ~/package/path/to/yourservice
  1. On gRPC server side, implement the new service
func RegisterServer(s *grpc.Server) {
       proto.RegisterTestServiceServer(s, &TestService{})
+      proto.RegisterCatServiceServer(s, &CatService{})
}

+type CatService struct {
+}

+func (c *CatService) Meow(ctx context.Context, req *proto.MeowRequest) (*proto.MeowResponse, error) {
+      return &proto.MeowResponse{Message: "Meow!"}, nil
+}
  1. On HTTP server side, register the new service
func GrpcClient(conn *grpc.ClientConn) map[string]interface{} {
       return map[string]interface{}{
               "TestService": proto.NewTestServiceClient(conn),
+              "CatService": proto.NewCatServiceClient(conn),
       }
}

DONE!

Thrift

  1. Define new service in .thrift file
+struct MeowResponse {
+ 1: string message,
+}

+service CatService {
+  MeowResponse Meow (1:string msg)
+}
  1. Modify service.yaml, add new APIs
config:
-  thrift_service_name: TestService
+  thrift_service_name: TestService,CatService
urlmapping:
+ - GET /cat/meow CatService Meow
  1. Generate new code
$ turbo generate package/path/to/yourservice -r thrift -I ~/package/path/to/yourservice
  1. On server side, implement the new service
func TProcessor() map[string]thrift.TProcessor {
       return map[string]thrift.TProcessor{
               "TestService": gen.NewTestServiceProcessor(TestService{}),
+              "CatService": gen.NewCatServiceProcessor(CatService{}),
       }
}

+type CatService struct {
+}

+func (c CatService) Meow(msg string) (r *gen.MeowResponse, err error) {
+      return &gen.MeowResponse{Message: msg}, nil
+}
  1. On HTTP server side, register the new service
func ThriftClient(trans thrift.TTransport, f thrift.TProtocolFactory) map[string]interface{} {
       iprot := f.GetProtocol(trans)
       return map[string]interface{}{
               "TestService": t.NewTestServiceClientProtocol(trans, iprot, thrift.NewTMultiplexedProtocol(iprot, "TestService")),
+              "CatService": t.NewCatServiceClientProtocol(trans, iprot, thrift.NewTMultiplexedProtocol(iprot, "CatService")),
       }
}

完成!