gRPC 的route_guide例子

 

本文的例子代码在: https://github.com/grpc/grpc-go/tree/master/examples/route_guide

功能就类似目前LBS一样,在每个位置上报一些文字信息, 上报方式有多种。

 

在 .proto 文件中定义服务

在 .proto 文件中定义一个服务很简单, 就像如下的代码:

service RouteGuide {
   ...
}

定义rpc的方法,需要指定他们的 request 和response 类型。gRPC 可以定义四种类型的方法,这个 RouteGuide 服务例子中都会出现。

1、就像普通函数调用一样,

客户端带着 stub 发送请求,然后等服务器端返回。

// Points are represented as latitude-longitude pairs in the E7 representation
// (degrees multiplied by 10**7 and rounded to the nearest integer).
// Latitudes should be in the range +/- 90 degrees and longitude should be in
// the range +/- 180 degrees (inclusive).
message Point {
  int32 latitude = 1;
  int32 longitude = 2;
}

// A feature names something at a given point.
//
// If a feature could not be named, the name is empty.
message Feature {
  // The name of the feature.
  string name = 1;
  // The point where the feature is detected.
  Point location = 2;
}

 

  // A simple RPC.
  //
  // Obtains the feature at a given position.
  //
  // If no feature is found for the given point, a feature with an empty name
  // should be returned.
  rpc GetFeature(Point) returns (Feature) {}

2、服务器端返回的是个RPC的流

客户端发送请求到服务器端,并获得一个流读取消息的序列。 客户端从返回的流中读取数据。 注意这里用了 stream 这个关键字。

// A latitude-longitude rectangle, represented as two diagonally opposite

// points "lo" and "hi".

message Rectangle {

    // One corner of the rectangle.

    Point lo = 1;

    // The other corner of the rectangle.

    Point hi = 2;

}

// A server-to-client streaming RPC.

//

// Obtains the Features available within the given Rectangle. Results are

// streamed rather than returned at once (e.g. in a response message with a

// repeated field), as the rectangle may cover a large area and contain a

// huge number of features.

rpc ListFeatures(Rectangle) returns (stream Feature) {}

 

3、客户端用流传输,服务器端正常。

客户端将消息写入流的序列,并将它们发送到服务器。一旦客户端已经写完了消息,客户端等待服务器读取所有这些,返回其响应。

// A RouteSummary is received in response to a RecordRoute rpc.

//

// It contains the number of individual points received, the number of

// detected features, and the total distance covered as the cumulative sum of

// the distance between each point.

message RouteSummary {

      // The number of points received.

      int32 point_count = 1;

      // The number of known features passed while traversing the route.

      int32 feature_count = 2;

      // The distance covered in metres.

      int32 distance = 3;

      // The duration of the traversal in seconds.

      int32 elapsed_time = 4;

}

// A client-to-server streaming RPC.

//

// Accepts a stream of Points on a route being traversed, returning a

// RouteSummary when traversal is completed.

rpc RecordRoute(stream Point) returns (RouteSummary) {}

4、服务器和客户端都用流来处理,即双向流

两个流独立运行,所以客户端和服务器端都可以读取和写入任何他们喜欢的东西。

// A RouteNote is a message sent while at a given point.

message RouteNote {

      // The location from which the message is sent.

      Point location = 1;

      // The message to be sent.

      string message = 2;

}

// A Bidirectional streaming RPC.

//

// Accepts a stream of RouteNotes sent while a route is being traversed,

// while receiving other RouteNotes (e.g. from other users).

rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}

 

 

产生 客户端和服务器端代码

有一个封装好的 shell 脚本在 https://github.com/grpc/grpc-go/blob/master/codegen.sh 

这个工具各种依赖的安装方法请参考: http://www.cnblogs.com/ghj1976/p/4564133.html

我们这里执行的命令是:  ./codegen.sh ./examples/route_guide/proto/route_guide.proto

(SR`(MPP_~K07B@E467%_FR

 

这时候我们产生的文件是: 

https://github.com/grpc/grpc-go/blob/master/examples/route_guide/proto/route_guide.pb.go

这个产生的文件中, 既有公共类的相关信息,也有客户端和服务器端的代码。

 

服务器端相关代码

这部分代码在: https://github.com/grpc/grpc-go/blob/master/examples/route_guide/server/server.go

服务器端我们要做这些事情:

  • 实现上面 proto 文件产生的 服务器端接口
  • 服务器端运行 rpc 服务器去监听来自客户端的请求, 并将它们路由到正确的服务上。

 

实现 RouteGuideServer 接口

我们在 route_guide.pb.go 中可以看到我们需要实现的接口:

// Server API for RouteGuide service

type RouteGuideServer interface {
    // A simple RPC.
    //
    // Obtains the feature at a given position.
    //
    // If no feature is found for the given point, a feature with an empty name
    // should be returned.
    GetFeature(context.Context, *Point) (*Feature, error)


    // A server-to-client streaming RPC.
    //
    // Obtains the Features available within the given Rectangle.  Results are
    // streamed rather than returned at once (e.g. in a response message with a
    // repeated field), as the rectangle may cover a large area and contain a
    // huge number of features.
    ListFeatures(*Rectangle, RouteGuide_ListFeaturesServer) error


    // A client-to-server streaming RPC.
    //
    // Accepts a stream of Points on a route being traversed, returning a
    // RouteSummary when traversal is completed.
    RecordRoute(RouteGuide_RecordRouteServer) error


    // A Bidirectional streaming RPC.
    //
    // Accepts a stream of RouteNotes sent while a route is being traversed,
    // while receiving other RouteNotes (e.g. from other users).
    RouteChat(RouteGuide_RouteChatServer) error
}

 

simple RPC.

GetFeature 需要根据客户端传入的一个点, 返回数据库中对应的 Feature.

~I8SMJLLO{7VIQX78C83R7K

 

Server-side streaming RPC

返回所有在这个区域的 Feature。

6V]XF6(KYFZ6F1F6H1X3N9E

注意,我们这里用到 stream.Send 方法发送的结果数据。在发送完成或者发送除了错误时,才return 结束这个函数。

Client-side streaming RPC

客户端上通过 stream 上传一批点, 服务器端记录 点的个数、已知的feature数、总行驶距离、总时间消耗。

 

)V44Z8BC%)$GPZJT_5{2WOC

注意, 这里通过 stream.Recv 接收数据,通过 stream.SendAndClose 关闭返回流。

Bidirectional streaming RPC

服务器端接收客户端上报的位置信息流, 针对当前一个位置,回应这个位置的已有 位置信息流。

]ZVAUUR@SZ4)MFJAVZ@SB10

这里用的 stream.Recv() 接收,  stream.Send 发送。

 

开始服务

UM`C@I9Y{%GSLKPHXYSHN%T

开启服务我们做了下面步骤:

1、制定服务的监控端口, lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))

2、创建一个 gRPC 服务实例  grpc.NewServer().

3、在gRPC 服务实例上注册我们的服务实现  pb.RegisterRouteGuideServer(grpcServer, &routeGuideServer{})

4、调用 grpcServer.Serve(lis) 开启服务, 我们监控的端口做阻塞等待,知道该进程被杀死或者 Stop() 方法被调用。

 

编译服务器端

编译时,由于墙的原因, 有些依赖包需要特殊下载, 相关资料请参考:

http://www.cnblogs.com/ghj1976/p/4549602.html 

 

创建客户端

这部分代码可以在 https://github.com/grpc/grpc-go/blob/master/examples/route_guide/client/client.go 看到。

建立通道

要调用服务, 我们需要先创建一个 gRPC 通道 与服务器进行通讯, 我们这里通过 grpc.Dial 来指定服务器地址和端口来创建这个通道。

J1(LSNHJ{1XIJ4`D9EMHXCU

一旦gRPC通道建立后, 我们需要一个客户端stub去执行RPC,这里我们使用 .proto 文件生产的 NewRouteGuideClient 方法。

 

调用服务器端方法

 

simple RPC.

调用simple RPC 就像调用一个本地方法一样:

@MY~E$9)P}V4M075[17ML8H

7K[~WJ2S5E~O{B960[`OJV0

 

 

Server-side streaming RPC

跟服务器端接收流没啥差别, stream.Recv() 函数去读取。

IG]V{8%V_H4K[O@YMVGES2E

H%WU45}VK%O7[XKGP~V~AVS

 

Client-side streaming RPC

随机产生 一些坐标点, 然后通过 stream.Send 依次发送, 随后通过 stream.CloseAndRecv() 结束发送同时等待服务器端的返回。

EOP]R1W6(KEO~XMWY%S1O92

 

Bidirectional streaming RPC

独立开一个协程 通过 stream.Recv() 接收服务器端的内容, 同时主协程 轮流 通过 stream.Send 进行发送, 主协程完毕后, 调用  stream.CloseSend() , 并通过 waitc 来控制子协程的关闭。

EOP]R1W6(KEO~XMWY%S1O92[7]

 

程序运行效果截图:

localhost:client ghj1976$ ./client
2015/06/11 16:13:27 Getting feature for point (409146138, -746188906)
2015/06/11 16:13:27 name:"Berkshire Valley Management Area Trail, Jefferson, NJ, USA" location:<latitude:409146138 longitude:-746188906 >
2015/06/11 16:13:27 Getting feature for point (0, 0)
2015/06/11 16:13:27 location:<>
2015/06/11 16:13:27 Looking for features within lo:<latitude:400000000 longitude:-750000000 > hi:<latitude:420000000 longitude:-730000000 >
2015/06/11 16:13:27 name:"Patriots Path, Mendham, NJ 07945, USA" location:<latitude:407838351 longitude:-746143763 >
2015/06/11 16:13:27 name:"101 New Jersey 10, Whippany, NJ 07981, USA" location:<latitude:408122808 longitude:-743999179 >
2015/06/11 16:13:27 name:"U.S. 6, Shohola, PA 18458, USA" location:<latitude:413628156 longitude:-749015468 >
2015/06/11 16:13:27 name:"5 Conners Road, Kingston, NY 12401, USA" location:<latitude:419999544 longitude:-740371136 >
2015/06/11 16:13:27 name:"Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" location:<latitude:414008389 longitude:-743951297 >
2015/06/11 16:13:27 name:"287 Flugertown Road, Livingston Manor, NY 12758, USA" location:<latitude:419611318 longitude:-746524769 >
2015/06/11 16:13:27 name:"4001 Tremley Point Road, Linden, NJ 07036, USA" location:<latitude:406109563 longitude:-742186778 >
2015/06/11 16:13:27 name:"352 South Mountain Road, Wallkill, NY 12589, USA" location:<latitude:416802456 longitude:-742370183 >

2015/06/11 16:13:27 name:"Bailey Turn Road, Harriman, NY 10926, USA" location:<latitude:412950425 longitude:-741077389 > 
2015/06/11 16:13:27 name:"193-199 Wawayanda Road, Hewitt, NJ 07421, USA" location:<latitude:412144655 longitude:-743949739 > 
2015/06/11 16:13:27 name:"406-496 Ward Avenue, Pine Bush, NY 12566, USA" location:<latitude:415736605 longitude:-742847522 > 
2015/06/11 16:13:27 name:"162 Merrill Road, Highland Mills, NY 10930, USA" location:<latitude:413843930 longitude:-740501726 > 
2015/06/11 16:13:27 name:"Clinton Road, West Milford, NJ 07480, USA" location:<latitude:410873075 longitude:-744459023 > 
2015/06/11 16:13:27 name:"16 Old Brook Lane, Warwick, NY 10990, USA" location:<latitude:412346009 longitude:-744026814 > 
2015/06/11 16:13:27 name:"3 Drake Lane, Pennington, NJ 08534, USA" location:<latitude:402948455 longitude:-747903913 > 
2015/06/11 16:13:27 name:"6324 8th Avenue, Brooklyn, NY 11220, USA" location:<latitude:406337092 longitude:-740122226 > 
2015/06/11 16:13:27 name:"1 Merck Access Road, Whitehouse Station, NJ 08889, USA" location:<latitude:406421967 longitude:-747727624 > 
2015/06/11 16:13:27 name:"78-98 Schalck Road, Narrowsburg, NY 12764, USA" location:<latitude:416318082 longitude:-749677716 > 
2015/06/11 16:13:27 name:"282 Lakeview Drive Road, Highland Lake, NY 12743, USA" location:<latitude:415301720 longitude:-748416257 > 
2015/06/11 16:13:27 name:"330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" location:<latitude:402647019 longitude:-747071791 > 
2015/06/11 16:13:27 name:"New York State Reference Route 987E, Southfields, NY 10975, USA" location:<latitude:412567807 longitude:-741058078 > 
2015/06/11 16:13:27 name:"103-271 Tempaloni Road, Ellenville, NY 12428, USA" location:<latitude:416855156 longitude:-744420597 > 
2015/06/11 16:13:27 name:"1300 Airport Road, North Brunswick Township, NJ 08902, USA" location:<latitude:404663628 longitude:-744820157 > 
2015/06/11 16:13:27 location:<latitude:407113723 longitude:-749746483 > 
2015/06/11 16:13:27 location:<latitude:402133926 longitude:-743613249 > 
2015/06/11 16:13:27 location:<latitude:400273442 longitude:-741220915 > 
2015/06/11 16:13:27 location:<latitude:411236786 longitude:-744070769 > 
2015/06/11 16:13:27 name:"211-225 Plains Road, Augusta, NJ 07822, USA" location:<latitude:411633782 longitude:-746784970 > 
2015/06/11 16:13:27 location:<latitude:415830701 longitude:-742952812 > 
2015/06/11 16:13:27 name:"165 Pedersen Ridge Road, Milford, PA 18337, USA" location:<latitude:413447164 longitude:-748712898 > 
2015/06/11 16:13:27 name:"100-122 Locktown Road, Frenchtown, NJ 08825, USA" location:<latitude:405047245 longitude:-749800722 > 
2015/06/11 16:13:27 location:<latitude:418858923 longitude:-746156790 > 
2015/06/11 16:13:27 name:"650-652 Willi Hill Road, Swan Lake, NY 12783, USA" location:<latitude:417951888 longitude:-748484944 > 
2015/06/11 16:13:27 name:"26 East 3rd Street, New Providence, NJ 07974, USA" location:<latitude:407033786 longitude:-743977337 > 
2015/06/11 16:13:27 location:<latitude:417548014 longitude:-740075041 > 
2015/06/11 16:13:27 location:<latitude:410395868 longitude:-744972325 > 
2015/06/11 16:13:27 location:<latitude:404615353 longitude:-745129803 > 
2015/06/11 16:13:27 name:"611 Lawrence Avenue, Westfield, NJ 07090, USA" location:<latitude:406589790 longitude:-743560121 > 
2015/06/11 16:13:27 name:"18 Lannis Avenue, New Windsor, NY 12553, USA" location:<latitude:414653148 longitude:-740477477 > 
2015/06/11 16:13:27 name:"82-104 Amherst Avenue, Colonia, NJ 07067, USA" location:<latitude:405957808 longitude:-743255336 > 
2015/06/11 16:13:27 name:"170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" location:<latitude:411733589 longitude:-741648093 > 
2015/06/11 16:13:27 name:"1270 Lakes Road, Monroe, NY 10950, USA" location:<latitude:412676291 longitude:-742606606 > 
2015/06/11 16:13:27 name:"509-535 Alphano Road, Great Meadows, NJ 07838, USA" location:<latitude:409224445 longitude:-748286738 >

2015/06/11 16:13:27 name:"652 Garden Street, Elizabeth, NJ 07202, USA" location:<latitude:406523420 longitude:-742135517 > 
2015/06/11 16:13:27 name:"349 Sea Spray Court, Neptune City, NJ 07753, USA" location:<latitude:401827388 longitude:-740294537 > 
2015/06/11 16:13:27 name:"13-17 Stanley Street, West Milford, NJ 07480, USA" location:<latitude:410564152 longitude:-743685054 > 
2015/06/11 16:13:27 name:"47 Industrial Avenue, Teterboro, NJ 07608, USA" location:<latitude:408472324 longitude:-740726046 > 
2015/06/11 16:13:27 name:"5 White Oak Lane, Stony Point, NY 10980, USA" location:<latitude:412452168 longitude:-740214052 > 
2015/06/11 16:13:27 name:"Berkshire Valley Management Area Trail, Jefferson, NJ, USA" location:<latitude:409146138 longitude:-746188906 > 
2015/06/11 16:13:27 name:"1007 Jersey Avenue, New Brunswick, NJ 08901, USA" location:<latitude:404701380 longitude:-744781745 > 
2015/06/11 16:13:27 name:"6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" location:<latitude:409642566 longitude:-746017679 > 
2015/06/11 16:13:27 name:"1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" location:<latitude:408031728 longitude:-748645385 > 
2015/06/11 16:13:27 name:"367 Prospect Road, Chester, NY 10918, USA" location:<latitude:413700272 longitude:-742135189 > 
2015/06/11 16:13:27 name:"10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" location:<latitude:404310607 longitude:-740282632 > 
2015/06/11 16:13:27 name:"11 Ward Street, Mount Arlington, NJ 07856, USA" location:<latitude:409319800 longitude:-746201391 > 
2015/06/11 16:13:27 name:"300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" location:<latitude:406685311 longitude:-742108603 > 
2015/06/11 16:13:27 name:"43 Dreher Road, Roscoe, NY 12776, USA" location:<latitude:419018117 longitude:-749142781 > 
2015/06/11 16:13:27 name:"Swan Street, Pine Island, NY 10969, USA" location:<latitude:412856162 longitude:-745148837 > 
2015/06/11 16:13:27 name:"66 Pleasantview Avenue, Monticello, NY 12701, USA" location:<latitude:416560744 longitude:-746721964 > 
2015/06/11 16:13:27 location:<latitude:405314270 longitude:-749836354 > 
2015/06/11 16:13:27 location:<latitude:414219548 longitude:-743327440 > 
2015/06/11 16:13:27 name:"565 Winding Hills Road, Montgomery, NY 12549, USA" location:<latitude:415534177 longitude:-742900616 > 
2015/06/11 16:13:27 name:"231 Rocky Run Road, Glen Gardner, NJ 08826, USA" location:<latitude:406898530 longitude:-749127080 > 
2015/06/11 16:13:27 name:"100 Mount Pleasant Avenue, Newark, NJ 07104, USA" location:<latitude:407586880 longitude:-741670168 > 
2015/06/11 16:13:27 name:"517-521 Huntington Drive, Manchester Township, NJ 08759, USA" location:<latitude:400106455 longitude:-742870190 > 
2015/06/11 16:13:27 location:<latitude:400066188 longitude:-746793294 > 
2015/06/11 16:13:27 name:"40 Mountain Road, Napanoch, NY 12458, USA" location:<latitude:418803880 longitude:-744102673 > 
2015/06/11 16:13:27 location:<latitude:414204288 longitude:-747895140 > 
2015/06/11 16:13:27 location:<latitude:414777405 longitude:-740615601 > 
2015/06/11 16:13:27 name:"48 North Road, Forestburgh, NY 12777, USA" location:<latitude:415464475 longitude:-747175374 > 
2015/06/11 16:13:27 location:<latitude:404062378 longitude:-746376177 > 
2015/06/11 16:13:27 location:<latitude:405688272 longitude:-749285130 > 
2015/06/11 16:13:27 location:<latitude:400342070 longitude:-748788996 > 
2015/06/11 16:13:27 location:<latitude:401809022 longitude:-744157964 > 
2015/06/11 16:13:27 name:"9 Thompson Avenue, Leonardo, NJ 07737, USA" location:<latitude:404226644 longitude:-740517141 >

2015/06/11 16:13:27 location:<latitude:410322033 longitude:-747871659 > 
2015/06/11 16:13:27 location:<latitude:407100674 longitude:-747742727 > 
2015/06/11 16:13:27 name:"213 Bush Road, Stone Ridge, NY 12484, USA" location:<latitude:418811433 longitude:-741718005 > 
2015/06/11 16:13:27 location:<latitude:415034302 longitude:-743850945 > 
2015/06/11 16:13:27 location:<latitude:411349992 longitude:-743694161 > 
2015/06/11 16:13:27 name:"1-17 Bergen Court, New Brunswick, NJ 08901, USA" location:<latitude:404839914 longitude:-744759616 > 
2015/06/11 16:13:27 name:"35 Oakland Valley Road, Cuddebackville, NY 12729, USA" location:<latitude:414638017 longitude:-745957854 > 
2015/06/11 16:13:27 location:<latitude:412127800 longitude:-740173578 > 
2015/06/11 16:13:27 location:<latitude:401263460 longitude:-747964303 > 
2015/06/11 16:13:27 location:<latitude:412843391 longitude:-749086026 > 
2015/06/11 16:13:27 location:<latitude:418512773 longitude:-743067823 > 
2015/06/11 16:13:27 name:"42-102 Main Street, Belford, NJ 07718, USA" location:<latitude:404318328 longitude:-740835638 > 
2015/06/11 16:13:27 location:<latitude:419020746 longitude:-741172328 > 
2015/06/11 16:13:27 location:<latitude:404080723 longitude:-746119569 > 
2015/06/11 16:13:27 location:<latitude:401012643 longitude:-744035134 > 
2015/06/11 16:13:27 location:<latitude:404306372 longitude:-741079661 > 
2015/06/11 16:13:27 location:<latitude:403966326 longitude:-748519297 > 
2015/06/11 16:13:27 location:<latitude:405002031 longitude:-748407866 > 
2015/06/11 16:13:27 location:<latitude:409532885 longitude:-742200683 > 
2015/06/11 16:13:27 location:<latitude:416851321 longitude:-742674555 > 
2015/06/11 16:13:27 name:"3387 Richmond Terrace, Staten Island, NY 10303, USA" location:<latitude:406411633 longitude:-741722051 > 
2015/06/11 16:13:27 name:"261 Van Sickle Road, Goshen, NY 10924, USA" location:<latitude:413069058 longitude:-744597778 > 
2015/06/11 16:13:27 location:<latitude:418465462 longitude:-746859398 > 
2015/06/11 16:13:27 location:<latitude:411733222 longitude:-744228360 > 
2015/06/11 16:13:27 name:"3 Hasta Way, Newton, NJ 07860, USA" location:<latitude:410248224 longitude:-747127767 > 
2015/06/11 16:13:27 Traversing 34 points.
2015/06/11 16:13:27 Route summary: point_count:34 distance:307771635 
2015/06/11 16:13:27 Got message First message at point(0, 1)
2015/06/11 16:13:27 Got message Second message at point(0, 2)
2015/06/11 16:13:27 Got message Third message at point(0, 3)
2015/06/11 16:13:27 Got message First message at point(0, 1)
2015/06/11 16:13:27 Got message Fourth message at point(0, 1)
2015/06/11 16:13:27 Got message Second message at point(0, 2)
2015/06/11 16:13:27 Got message Fifth message at point(0, 2)
2015/06/11 16:13:27 Got message Third message at point(0, 3)
2015/06/11 16:13:27 Got message Sixth message at point(0, 3)
localhost:client ghj1976$

 

 

参考资料:

gRPC Basics: Go
https://github.com/grpc/grpc-common/blob/master/go/gotutorial.md

http://www.grpc.io/docs/tutorials/basic/go.html

原文地址:https://www.cnblogs.com/ghj1976/p/4569419.html