3 * Copyright 2015 gRPC authors.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 // Package main implements a simple gRPC client that demonstrates how to use gRPC-Go libraries
20 // to perform unary, client streaming, server streaming and full duplex RPCs.
22 // It interacts with the route guide service whose definition can be found in routeguide/route_guide.proto.
32 "golang.org/x/net/context"
33 "google.golang.org/grpc"
34 "google.golang.org/grpc/credentials"
35 pb "google.golang.org/grpc/examples/route_guide/routeguide"
36 "google.golang.org/grpc/testdata"
40 tls = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
41 caFile = flag.String("ca_file", "", "The file containning the CA root cert file")
42 serverAddr = flag.String("server_addr", "127.0.0.1:10000", "The server address in the format of host:port")
43 serverHostOverride = flag.String("server_host_override", "x.test.youtube.com", "The server name use to verify the hostname returned by TLS handshake")
46 // printFeature gets the feature for the given point.
47 func printFeature(client pb.RouteGuideClient, point *pb.Point) {
48 log.Printf("Getting feature for point (%d, %d)", point.Latitude, point.Longitude)
49 feature, err := client.GetFeature(context.Background(), point)
51 log.Fatalf("%v.GetFeatures(_) = _, %v: ", client, err)
56 // printFeatures lists all the features within the given bounding Rectangle.
57 func printFeatures(client pb.RouteGuideClient, rect *pb.Rectangle) {
58 log.Printf("Looking for features within %v", rect)
59 stream, err := client.ListFeatures(context.Background(), rect)
61 log.Fatalf("%v.ListFeatures(_) = _, %v", client, err)
64 feature, err := stream.Recv()
69 log.Fatalf("%v.ListFeatures(_) = _, %v", client, err)
75 // runRecordRoute sends a sequence of points to server and expects to get a RouteSummary from server.
76 func runRecordRoute(client pb.RouteGuideClient) {
77 // Create a random number of random points
78 r := rand.New(rand.NewSource(time.Now().UnixNano()))
79 pointCount := int(r.Int31n(100)) + 2 // Traverse at least two points
80 var points []*pb.Point
81 for i := 0; i < pointCount; i++ {
82 points = append(points, randomPoint(r))
84 log.Printf("Traversing %d points.", len(points))
85 stream, err := client.RecordRoute(context.Background())
87 log.Fatalf("%v.RecordRoute(_) = _, %v", client, err)
89 for _, point := range points {
90 if err := stream.Send(point); err != nil {
91 log.Fatalf("%v.Send(%v) = %v", stream, point, err)
94 reply, err := stream.CloseAndRecv()
96 log.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil)
98 log.Printf("Route summary: %v", reply)
101 // runRouteChat receives a sequence of route notes, while sending notes for various locations.
102 func runRouteChat(client pb.RouteGuideClient) {
103 notes := []*pb.RouteNote{
104 {&pb.Point{Latitude: 0, Longitude: 1}, "First message"},
105 {&pb.Point{Latitude: 0, Longitude: 2}, "Second message"},
106 {&pb.Point{Latitude: 0, Longitude: 3}, "Third message"},
107 {&pb.Point{Latitude: 0, Longitude: 1}, "Fourth message"},
108 {&pb.Point{Latitude: 0, Longitude: 2}, "Fifth message"},
109 {&pb.Point{Latitude: 0, Longitude: 3}, "Sixth message"},
111 stream, err := client.RouteChat(context.Background())
113 log.Fatalf("%v.RouteChat(_) = _, %v", client, err)
115 waitc := make(chan struct{})
118 in, err := stream.Recv()
125 log.Fatalf("Failed to receive a note : %v", err)
127 log.Printf("Got message %s at point(%d, %d)", in.Message, in.Location.Latitude, in.Location.Longitude)
130 for _, note := range notes {
131 if err := stream.Send(note); err != nil {
132 log.Fatalf("Failed to send a note: %v", err)
139 func randomPoint(r *rand.Rand) *pb.Point {
140 lat := (r.Int31n(180) - 90) * 1e7
141 long := (r.Int31n(360) - 180) * 1e7
142 return &pb.Point{Latitude: lat, Longitude: long}
147 var opts []grpc.DialOption
150 *caFile = testdata.Path("ca.pem")
152 creds, err := credentials.NewClientTLSFromFile(*caFile, *serverHostOverride)
154 log.Fatalf("Failed to create TLS credentials %v", err)
156 opts = append(opts, grpc.WithTransportCredentials(creds))
158 opts = append(opts, grpc.WithInsecure())
160 conn, err := grpc.Dial(*serverAddr, opts...)
162 log.Fatalf("fail to dial: %v", err)
165 client := pb.NewRouteGuideClient(conn)
167 // Looking for a valid feature
168 printFeature(client, &pb.Point{Latitude: 409146138, Longitude: -746188906})
171 printFeature(client, &pb.Point{Latitude: 0, Longitude: 0})
173 // Looking for features between 40, -75 and 42, -73.
174 printFeatures(client, &pb.Rectangle{
175 Lo: &pb.Point{Latitude: 400000000, Longitude: -750000000},
176 Hi: &pb.Point{Latitude: 420000000, Longitude: -730000000},
180 runRecordRoute(client)