diff --git a/examples/features/multiplex/README.md b/examples/features/multiplex/README.md new file mode 100644 index 000000000..803a8d772 --- /dev/null +++ b/examples/features/multiplex/README.md @@ -0,0 +1,12 @@ +# Multiplex + +A `grpc.ClientConn` can be shared by two stubs and two services can share a +`grpc.Server`. This example illustrates how to perform both types of sharing. + +``` +go run server/main.go +``` + +``` +go run client/main.go +``` diff --git a/examples/features/multiplex/client/main.go b/examples/features/multiplex/client/main.go new file mode 100644 index 000000000..43b3fa5c4 --- /dev/null +++ b/examples/features/multiplex/client/main.go @@ -0,0 +1,76 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package main + +import ( + "context" + "fmt" + "log" + "time" + + "google.golang.org/grpc" + ecpb "google.golang.org/grpc/examples/features/proto/echo" + hwpb "google.golang.org/grpc/examples/helloworld/helloworld" +) + +const ( + address = "localhost:50051" +) + +// callSayHello calls SayHello on c with the given name, and prints the +// response. +func callSayHello(c hwpb.GreeterClient, name string) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + r, err := c.SayHello(ctx, &hwpb.HelloRequest{Name: name}) + if err != nil { + log.Fatalf("client.SayHello(_) = _, %v", err) + } + fmt.Println("Greeting: ", r.Message) +} + +func callUnaryEcho(client ecpb.EchoClient, message string) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + resp, err := client.UnaryEcho(ctx, &ecpb.EchoRequest{Message: message}) + if err != nil { + log.Fatalf("client.UnaryEcho(_) = _, %v: ", err) + } + fmt.Println("UnaryEcho: ", resp.Message) +} + +func main() { + // Set up a connection to the server. + conn, err := grpc.Dial(address, grpc.WithInsecure()) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + + fmt.Println("--- calling helloworld.Greeter/SayHello ---") + // Make a greeter client and send an RPC. + hwc := hwpb.NewGreeterClient(conn) + callSayHello(hwc, "multiplex") + + fmt.Println() + fmt.Println("--- calling routeguide.RouteGuide/GetFeature ---") + // Make a routeguild client with the same ClientConn. + rgc := ecpb.NewEchoClient(conn) + callUnaryEcho(rgc, "this is examples/multiplex") +} diff --git a/examples/features/multiplex/server/main.go b/examples/features/multiplex/server/main.go new file mode 100644 index 000000000..de8bc1572 --- /dev/null +++ b/examples/features/multiplex/server/main.go @@ -0,0 +1,79 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package main + +import ( + "context" + "log" + "net" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + ecpb "google.golang.org/grpc/examples/features/proto/echo" + hwpb "google.golang.org/grpc/examples/helloworld/helloworld" + "google.golang.org/grpc/status" +) + +const ( + port = ":50051" +) + +// hwServer is used to implement helloworld.GreeterServer. +type hwServer struct{} + +// SayHello implements helloworld.GreeterServer +func (s *hwServer) SayHello(ctx context.Context, in *hwpb.HelloRequest) (*hwpb.HelloReply, error) { + return &hwpb.HelloReply{Message: "Hello " + in.Name}, nil +} + +type ecServer struct{} + +func (s *ecServer) UnaryEcho(ctx context.Context, req *ecpb.EchoRequest) (*ecpb.EchoResponse, error) { + return &ecpb.EchoResponse{Message: req.Message}, nil +} + +func (s *ecServer) ServerStreamingEcho(*ecpb.EchoRequest, ecpb.Echo_ServerStreamingEchoServer) error { + return status.Errorf(codes.Unimplemented, "not implemented") +} + +func (s *ecServer) ClientStreamingEcho(ecpb.Echo_ClientStreamingEchoServer) error { + return status.Errorf(codes.Unimplemented, "not implemented") +} + +func (s *ecServer) BidirectionalStreamingEcho(ecpb.Echo_BidirectionalStreamingEchoServer) error { + return status.Errorf(codes.Unimplemented, "not implemented") +} + +func main() { + lis, err := net.Listen("tcp", port) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + + // Register Greeter on the server. + hwpb.RegisterGreeterServer(s, &hwServer{}) + + // Register RouteGuide on the same server. + ecpb.RegisterEchoServer(s, &ecServer{}) + + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +}