multiplex_server.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # Copyright 2016 gRPC authors.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. """A gRPC server servicing both Greeter and RouteGuide RPCs."""
  15. from concurrent import futures
  16. import logging
  17. import math
  18. import time
  19. import grpc
  20. import helloworld_pb2
  21. import helloworld_pb2_grpc
  22. import route_guide_pb2
  23. import route_guide_pb2_grpc
  24. import route_guide_resources
  25. def _get_feature(feature_db, point):
  26. """Returns Feature at given location or None."""
  27. for feature in feature_db:
  28. if feature.location == point:
  29. return feature
  30. return None
  31. def _get_distance(start, end):
  32. """Distance between two points."""
  33. coord_factor = 10000000.0
  34. lat_1 = start.latitude / coord_factor
  35. lat_2 = end.latitude / coord_factor
  36. lon_1 = start.longitude / coord_factor
  37. lon_2 = end.longitude / coord_factor
  38. lat_rad_1 = math.radians(lat_1)
  39. lat_rad_2 = math.radians(lat_2)
  40. delta_lat_rad = math.radians(lat_2 - lat_1)
  41. delta_lon_rad = math.radians(lon_2 - lon_1)
  42. a = (pow(math.sin(delta_lat_rad / 2), 2) +
  43. (math.cos(lat_rad_1) * math.cos(lat_rad_2) *
  44. pow(math.sin(delta_lon_rad / 2), 2)))
  45. c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
  46. R = 6371000
  47. # metres
  48. return R * c
  49. class _GreeterServicer(helloworld_pb2_grpc.GreeterServicer):
  50. def SayHello(self, request, context):
  51. return helloworld_pb2.HelloReply(
  52. message='Hello, {}!'.format(request.name))
  53. class _RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
  54. """Provides methods that implement functionality of route guide server."""
  55. def __init__(self):
  56. self.db = route_guide_resources.read_route_guide_database()
  57. def GetFeature(self, request, context):
  58. feature = _get_feature(self.db, request)
  59. if feature is None:
  60. return route_guide_pb2.Feature(name="", location=request)
  61. else:
  62. return feature
  63. def ListFeatures(self, request, context):
  64. left = min(request.lo.longitude, request.hi.longitude)
  65. right = max(request.lo.longitude, request.hi.longitude)
  66. top = max(request.lo.latitude, request.hi.latitude)
  67. bottom = min(request.lo.latitude, request.hi.latitude)
  68. for feature in self.db:
  69. if (feature.location.longitude >= left and
  70. feature.location.longitude <= right and
  71. feature.location.latitude >= bottom and
  72. feature.location.latitude <= top):
  73. yield feature
  74. def RecordRoute(self, request_iterator, context):
  75. point_count = 0
  76. feature_count = 0
  77. distance = 0.0
  78. prev_point = None
  79. start_time = time.time()
  80. for point in request_iterator:
  81. point_count += 1
  82. if _get_feature(self.db, point):
  83. feature_count += 1
  84. if prev_point:
  85. distance += _get_distance(prev_point, point)
  86. prev_point = point
  87. elapsed_time = time.time() - start_time
  88. return route_guide_pb2.RouteSummary(point_count=point_count,
  89. feature_count=feature_count,
  90. distance=int(distance),
  91. elapsed_time=int(elapsed_time))
  92. def RouteChat(self, request_iterator, context):
  93. prev_notes = []
  94. for new_note in request_iterator:
  95. for prev_note in prev_notes:
  96. if prev_note.location == new_note.location:
  97. yield prev_note
  98. prev_notes.append(new_note)
  99. def serve():
  100. server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
  101. helloworld_pb2_grpc.add_GreeterServicer_to_server(_GreeterServicer(),
  102. server)
  103. route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
  104. _RouteGuideServicer(), server)
  105. server.add_insecure_port('[::]:50051')
  106. server.start()
  107. server.wait_for_termination()
  108. if __name__ == '__main__':
  109. logging.basicConfig()
  110. serve()