1*cc02d7e2SAndroid Build Coastguard Worker# Copyright 2019 gRPC authors. 2*cc02d7e2SAndroid Build Coastguard Worker# 3*cc02d7e2SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*cc02d7e2SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*cc02d7e2SAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*cc02d7e2SAndroid Build Coastguard Worker# 7*cc02d7e2SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*cc02d7e2SAndroid Build Coastguard Worker# 9*cc02d7e2SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*cc02d7e2SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*cc02d7e2SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*cc02d7e2SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*cc02d7e2SAndroid Build Coastguard Worker# limitations under the License. 14*cc02d7e2SAndroid Build Coastguard Worker"""The example of four ways of data transmission using gRPC in Python.""" 15*cc02d7e2SAndroid Build Coastguard Worker 16*cc02d7e2SAndroid Build Coastguard Workerfrom concurrent import futures 17*cc02d7e2SAndroid Build Coastguard Workerfrom threading import Thread 18*cc02d7e2SAndroid Build Coastguard Worker 19*cc02d7e2SAndroid Build Coastguard Workerimport grpc 20*cc02d7e2SAndroid Build Coastguard Worker 21*cc02d7e2SAndroid Build Coastguard Workerimport demo_pb2 22*cc02d7e2SAndroid Build Coastguard Workerimport demo_pb2_grpc 23*cc02d7e2SAndroid Build Coastguard Worker 24*cc02d7e2SAndroid Build Coastguard Worker__all__ = "DemoServer" 25*cc02d7e2SAndroid Build Coastguard WorkerSERVER_ADDRESS = "localhost:23333" 26*cc02d7e2SAndroid Build Coastguard WorkerSERVER_ID = 1 27*cc02d7e2SAndroid Build Coastguard Worker 28*cc02d7e2SAndroid Build Coastguard Worker 29*cc02d7e2SAndroid Build Coastguard Workerclass DemoServer(demo_pb2_grpc.GRPCDemoServicer): 30*cc02d7e2SAndroid Build Coastguard Worker # 一元模式(在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应) 31*cc02d7e2SAndroid Build Coastguard Worker # unary-unary(In a single call, the client can only send request once, and the server can 32*cc02d7e2SAndroid Build Coastguard Worker # only respond once.) 33*cc02d7e2SAndroid Build Coastguard Worker def SimpleMethod(self, request, context): 34*cc02d7e2SAndroid Build Coastguard Worker print( 35*cc02d7e2SAndroid Build Coastguard Worker "SimpleMethod called by client(%d) the message: %s" 36*cc02d7e2SAndroid Build Coastguard Worker % (request.client_id, request.request_data) 37*cc02d7e2SAndroid Build Coastguard Worker ) 38*cc02d7e2SAndroid Build Coastguard Worker response = demo_pb2.Response( 39*cc02d7e2SAndroid Build Coastguard Worker server_id=SERVER_ID, 40*cc02d7e2SAndroid Build Coastguard Worker response_data="Python server SimpleMethod Ok!!!!", 41*cc02d7e2SAndroid Build Coastguard Worker ) 42*cc02d7e2SAndroid Build Coastguard Worker return response 43*cc02d7e2SAndroid Build Coastguard Worker 44*cc02d7e2SAndroid Build Coastguard Worker # 客户端流模式(在一次调用中, 客户端可以多次向服务器传输数据, 但是服务器只能返回一次响应) 45*cc02d7e2SAndroid Build Coastguard Worker # stream-unary (In a single call, the client can transfer data to the server several times, 46*cc02d7e2SAndroid Build Coastguard Worker # but the server can only return a response once.) 47*cc02d7e2SAndroid Build Coastguard Worker def ClientStreamingMethod(self, request_iterator, context): 48*cc02d7e2SAndroid Build Coastguard Worker print("ClientStreamingMethod called by client...") 49*cc02d7e2SAndroid Build Coastguard Worker for request in request_iterator: 50*cc02d7e2SAndroid Build Coastguard Worker print( 51*cc02d7e2SAndroid Build Coastguard Worker "recv from client(%d), message= %s" 52*cc02d7e2SAndroid Build Coastguard Worker % (request.client_id, request.request_data) 53*cc02d7e2SAndroid Build Coastguard Worker ) 54*cc02d7e2SAndroid Build Coastguard Worker response = demo_pb2.Response( 55*cc02d7e2SAndroid Build Coastguard Worker server_id=SERVER_ID, 56*cc02d7e2SAndroid Build Coastguard Worker response_data="Python server ClientStreamingMethod ok", 57*cc02d7e2SAndroid Build Coastguard Worker ) 58*cc02d7e2SAndroid Build Coastguard Worker return response 59*cc02d7e2SAndroid Build Coastguard Worker 60*cc02d7e2SAndroid Build Coastguard Worker # 服务端流模式(在一次调用中, 客户端只能一次向服务器传输数据, 但是服务器可以多次返回响应) 61*cc02d7e2SAndroid Build Coastguard Worker # unary-stream (In a single call, the client can only transmit data to the server at one time, 62*cc02d7e2SAndroid Build Coastguard Worker # but the server can return the response many times.) 63*cc02d7e2SAndroid Build Coastguard Worker def ServerStreamingMethod(self, request, context): 64*cc02d7e2SAndroid Build Coastguard Worker print( 65*cc02d7e2SAndroid Build Coastguard Worker "ServerStreamingMethod called by client(%d), message= %s" 66*cc02d7e2SAndroid Build Coastguard Worker % (request.client_id, request.request_data) 67*cc02d7e2SAndroid Build Coastguard Worker ) 68*cc02d7e2SAndroid Build Coastguard Worker 69*cc02d7e2SAndroid Build Coastguard Worker # 创建一个生成器 70*cc02d7e2SAndroid Build Coastguard Worker # create a generator 71*cc02d7e2SAndroid Build Coastguard Worker def response_messages(): 72*cc02d7e2SAndroid Build Coastguard Worker for i in range(5): 73*cc02d7e2SAndroid Build Coastguard Worker response = demo_pb2.Response( 74*cc02d7e2SAndroid Build Coastguard Worker server_id=SERVER_ID, 75*cc02d7e2SAndroid Build Coastguard Worker response_data="send by Python server, message=%d" % i, 76*cc02d7e2SAndroid Build Coastguard Worker ) 77*cc02d7e2SAndroid Build Coastguard Worker yield response 78*cc02d7e2SAndroid Build Coastguard Worker 79*cc02d7e2SAndroid Build Coastguard Worker return response_messages() 80*cc02d7e2SAndroid Build Coastguard Worker 81*cc02d7e2SAndroid Build Coastguard Worker # 双向流模式 (在一次调用中, 客户端和服务器都可以向对方多次收发数据) 82*cc02d7e2SAndroid Build Coastguard Worker # stream-stream (In a single call, both client and server can send and receive data 83*cc02d7e2SAndroid Build Coastguard Worker # to each other multiple times.) 84*cc02d7e2SAndroid Build Coastguard Worker def BidirectionalStreamingMethod(self, request_iterator, context): 85*cc02d7e2SAndroid Build Coastguard Worker print("BidirectionalStreamingMethod called by client...") 86*cc02d7e2SAndroid Build Coastguard Worker 87*cc02d7e2SAndroid Build Coastguard Worker # 开启一个子线程去接收数据 88*cc02d7e2SAndroid Build Coastguard Worker # Open a sub thread to receive data 89*cc02d7e2SAndroid Build Coastguard Worker def parse_request(): 90*cc02d7e2SAndroid Build Coastguard Worker for request in request_iterator: 91*cc02d7e2SAndroid Build Coastguard Worker print( 92*cc02d7e2SAndroid Build Coastguard Worker "recv from client(%d), message= %s" 93*cc02d7e2SAndroid Build Coastguard Worker % (request.client_id, request.request_data) 94*cc02d7e2SAndroid Build Coastguard Worker ) 95*cc02d7e2SAndroid Build Coastguard Worker 96*cc02d7e2SAndroid Build Coastguard Worker t = Thread(target=parse_request) 97*cc02d7e2SAndroid Build Coastguard Worker t.start() 98*cc02d7e2SAndroid Build Coastguard Worker 99*cc02d7e2SAndroid Build Coastguard Worker for i in range(5): 100*cc02d7e2SAndroid Build Coastguard Worker yield demo_pb2.Response( 101*cc02d7e2SAndroid Build Coastguard Worker server_id=SERVER_ID, 102*cc02d7e2SAndroid Build Coastguard Worker response_data="send by Python server, message= %d" % i, 103*cc02d7e2SAndroid Build Coastguard Worker ) 104*cc02d7e2SAndroid Build Coastguard Worker 105*cc02d7e2SAndroid Build Coastguard Worker t.join() 106*cc02d7e2SAndroid Build Coastguard Worker 107*cc02d7e2SAndroid Build Coastguard Worker 108*cc02d7e2SAndroid Build Coastguard Workerdef main(): 109*cc02d7e2SAndroid Build Coastguard Worker server = grpc.server(futures.ThreadPoolExecutor()) 110*cc02d7e2SAndroid Build Coastguard Worker 111*cc02d7e2SAndroid Build Coastguard Worker demo_pb2_grpc.add_GRPCDemoServicer_to_server(DemoServer(), server) 112*cc02d7e2SAndroid Build Coastguard Worker 113*cc02d7e2SAndroid Build Coastguard Worker server.add_insecure_port(SERVER_ADDRESS) 114*cc02d7e2SAndroid Build Coastguard Worker print("------------------start Python GRPC server") 115*cc02d7e2SAndroid Build Coastguard Worker server.start() 116*cc02d7e2SAndroid Build Coastguard Worker server.wait_for_termination() 117*cc02d7e2SAndroid Build Coastguard Worker 118*cc02d7e2SAndroid Build Coastguard Worker # If raise Error: 119*cc02d7e2SAndroid Build Coastguard Worker # AttributeError: '_Server' object has no attribute 'wait_for_termination' 120*cc02d7e2SAndroid Build Coastguard Worker # You can use the following code instead: 121*cc02d7e2SAndroid Build Coastguard Worker # import time 122*cc02d7e2SAndroid Build Coastguard Worker # while 1: 123*cc02d7e2SAndroid Build Coastguard Worker # time.sleep(10) 124*cc02d7e2SAndroid Build Coastguard Worker 125*cc02d7e2SAndroid Build Coastguard Worker 126*cc02d7e2SAndroid Build Coastguard Workerif __name__ == "__main__": 127*cc02d7e2SAndroid Build Coastguard Worker main() 128