gRPC阅读日记(三)
普通RPC
先来看看简单gRPC的实现,GetFeature处理单点消息的请求,并返回相应点的特征信息。
func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {
for _, feature := range s.savedFeatures {
if proto.Equal(feature.Location, point) {
return feature, nil
}
}
// No feature was found, return an unnamed feature
return &pb.Feature{Location: point}, nil
}
该方法需要两个参数,一个是给rpc的上下文处理器,另一个就是来自客户端的point消息,也就是现在我们在.proto文件中预定义好的请求类型。返回也是先前定义的feature消息,相应类型,以及error。
从实现中可以看到,该RPC是将取到的点,与自己的数据库中的信息做比对,如果有则返回该点的内容且error为nil,如果没有则返回该点,error为nil。
服务端的流式RPC
服务侧的流式RPC会相应多条数据给客户端。
func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error {
for _, feature := range s.savedFeatures {
if inRange(feature.Location, rect) {
if err := stream.Send(feature); err != nil {
return err
}
}
}
return nil
}
从实现上看,这次收到的是带有经纬范围的请求,所以服务端通过流式相应返回多条数据
如果查找到范围内的数据则返回,发送失败则返回错误,如果没有查找到返回nil
更加特殊的是,相比较于简单的请求类型,和相应类型,这次使用了更加复杂的请求对象,以及另一个特殊的对象RouteGuide_ListFeaturesServer去写响应,因为我们需要使用他的方法stream.send()
还有一点不同在于,在上一个普通的rpc中,我们返回nil error去告诉客户端,响应已经写完结束了,但在这次如果send中发生了任何错误,我们就会返回非nil的error回去,gRPC层将会将它该错误翻译成恰当的rpc状态然后发送回去。
网友评论