123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /*
- *
- * Copyright 2015 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 implements a simple gRPC client that demonstrates how to use gRPC-Go libraries
- // to perform unary, client streaming, server streaming and full duplex RPCs.
- //
- // It interacts with the route guide service whose definition can be found in routeguide/route_guide.proto.
- package main
- import (
- "context"
- "flag"
- "io"
- "log"
- "math/rand"
- "time"
- "google.golang.org/grpc"
- "google.golang.org/grpc/credentials"
- pb "google.golang.org/grpc/examples/route_guide/routeguide"
- "google.golang.org/grpc/testdata"
- )
- var (
- tls = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
- caFile = flag.String("ca_file", "", "The file containning the CA root cert file")
- serverAddr = flag.String("server_addr", "127.0.0.1:10000", "The server address in the format of host:port")
- serverHostOverride = flag.String("server_host_override", "x.test.youtube.com", "The server name use to verify the hostname returned by TLS handshake")
- )
- // printFeature gets the feature for the given point.
- func printFeature(client pb.RouteGuideClient, point *pb.Point) {
- log.Printf("Getting feature for point (%d, %d)", point.Latitude, point.Longitude)
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
- defer cancel()
- feature, err := client.GetFeature(ctx, point)
- if err != nil {
- log.Fatalf("%v.GetFeatures(_) = _, %v: ", client, err)
- }
- log.Println(feature)
- }
- // printFeatures lists all the features within the given bounding Rectangle.
- func printFeatures(client pb.RouteGuideClient, rect *pb.Rectangle) {
- log.Printf("Looking for features within %v", rect)
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
- defer cancel()
- stream, err := client.ListFeatures(ctx, rect)
- if err != nil {
- log.Fatalf("%v.ListFeatures(_) = _, %v", client, err)
- }
- for {
- feature, err := stream.Recv()
- if err == io.EOF {
- break
- }
- if err != nil {
- log.Fatalf("%v.ListFeatures(_) = _, %v", client, err)
- }
- log.Println(feature)
- }
- }
- // runRecordRoute sends a sequence of points to server and expects to get a RouteSummary from server.
- func runRecordRoute(client pb.RouteGuideClient) {
- // Create a random number of random points
- r := rand.New(rand.NewSource(time.Now().UnixNano()))
- pointCount := int(r.Int31n(100)) + 2 // Traverse at least two points
- var points []*pb.Point
- for i := 0; i < pointCount; i++ {
- points = append(points, randomPoint(r))
- }
- log.Printf("Traversing %d points.", len(points))
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
- defer cancel()
- stream, err := client.RecordRoute(ctx)
- if err != nil {
- log.Fatalf("%v.RecordRoute(_) = _, %v", client, err)
- }
- for _, point := range points {
- if err := stream.Send(point); err != nil {
- log.Fatalf("%v.Send(%v) = %v", stream, point, err)
- }
- }
- reply, err := stream.CloseAndRecv()
- if err != nil {
- log.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil)
- }
- log.Printf("Route summary: %v", reply)
- }
- // runRouteChat receives a sequence of route notes, while sending notes for various locations.
- func runRouteChat(client pb.RouteGuideClient) {
- notes := []*pb.RouteNote{
- {Location: &pb.Point{Latitude: 0, Longitude: 1}, Message: "First message"},
- {Location: &pb.Point{Latitude: 0, Longitude: 2}, Message: "Second message"},
- {Location: &pb.Point{Latitude: 0, Longitude: 3}, Message: "Third message"},
- {Location: &pb.Point{Latitude: 0, Longitude: 1}, Message: "Fourth message"},
- {Location: &pb.Point{Latitude: 0, Longitude: 2}, Message: "Fifth message"},
- {Location: &pb.Point{Latitude: 0, Longitude: 3}, Message: "Sixth message"},
- }
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
- defer cancel()
- stream, err := client.RouteChat(ctx)
- if err != nil {
- log.Fatalf("%v.RouteChat(_) = _, %v", client, err)
- }
- waitc := make(chan struct{})
- go func() {
- for {
- in, err := stream.Recv()
- if err == io.EOF {
- // read done.
- close(waitc)
- return
- }
- if err != nil {
- log.Fatalf("Failed to receive a note : %v", err)
- }
- log.Printf("Got message %s at point(%d, %d)", in.Message, in.Location.Latitude, in.Location.Longitude)
- }
- }()
- for _, note := range notes {
- if err := stream.Send(note); err != nil {
- log.Fatalf("Failed to send a note: %v", err)
- }
- }
- stream.CloseSend()
- <-waitc
- }
- func randomPoint(r *rand.Rand) *pb.Point {
- lat := (r.Int31n(180) - 90) * 1e7
- long := (r.Int31n(360) - 180) * 1e7
- return &pb.Point{Latitude: lat, Longitude: long}
- }
- func main() {
- flag.Parse()
- var opts []grpc.DialOption
- if *tls {
- if *caFile == "" {
- *caFile = testdata.Path("ca.pem")
- }
- creds, err := credentials.NewClientTLSFromFile(*caFile, *serverHostOverride)
- if err != nil {
- log.Fatalf("Failed to create TLS credentials %v", err)
- }
- opts = append(opts, grpc.WithTransportCredentials(creds))
- } else {
- opts = append(opts, grpc.WithInsecure())
- }
- conn, err := grpc.Dial(*serverAddr, opts...)
- if err != nil {
- log.Fatalf("fail to dial: %v", err)
- }
- defer conn.Close()
- client := pb.NewRouteGuideClient(conn)
- // Looking for a valid feature
- printFeature(client, &pb.Point{Latitude: 409146138, Longitude: -746188906})
- // Feature missing.
- printFeature(client, &pb.Point{Latitude: 0, Longitude: 0})
- // Looking for features between 40, -75 and 42, -73.
- printFeatures(client, &pb.Rectangle{
- Lo: &pb.Point{Latitude: 400000000, Longitude: -750000000},
- Hi: &pb.Point{Latitude: 420000000, Longitude: -730000000},
- })
- // RecordRoute
- runRecordRoute(client)
- // RouteChat
- runRouteChat(client)
- }
|