xref: /aosp_15_r20/external/grpc-grpc/examples/python/data_transmission/server.py (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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