This article describes an example method in Python gRPC everyone to share, as follows:
Using Protocol Buffers cross-platform RPC system.
installation
Use pip
1
2
|
pip install grpcio
pip install grpcio
-
tools googleapis
-
common
-
protos
|
gRPC consists of two portions, grpcio gRPC and tools, which is provided by the plug and protocol buffer compiler generated code.
use
Written protocol buffer
Use gRPC first need to do is design protocol buffer. Create a new msg.proto
file.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
syntax
=
"proto3"
;
service MsgService {
rpc GetMsg (MsgRequest) returns (MsgResponse){}
}
message MsgRequest {
string name
=
1
;
}
message MsgResponse {
string msg
=
1
;
}
|
At the top of the news service, for example, first of all the provisions of the syntax used here is the proto3
syntax. Then use the service
keyword to define services, gRPC RPC offers four types of services, as defined herein, is the first single to respond to a single request, similar to a normal function call, the other to use a stream
keyword, put it in parentheses, on behalf of the data stream data. The study then later, this time to design a simple RPC.
After defining two message
, a structure is a request, a response to a result. Here indicates that this data structure is a string, protocol buffer can also be defined as int32, int64, double, float like. The initial value given here can easily fill in actual use, it will be given new value.
Generate interface code
Because before installing some auxiliary plug, use can be generated directly here.
1
|
python -m grpc_tools.protoc -I . --pythoout=. --grpc_python_out=. msg.proto
|
Here two files are generated, msg_pb2.py
and msg_pb2_grpc.py
. These two documents for the subsequent service and client use. The former is the definition of a number of variables, such as _MSGREQUEST
the request contains the names of functions, variables acceptable, in fact or msg.proto
thing in the definition.
Create a server
First you need to import the necessary RPC packet, and just two files generated.
1
2
3
|
import
grpc
import
msg_pb2
import
msg_pb2_grpc
|
Because RPC should run for a long time, taking into account the performance, but also need to use concurrency library.
1
2
3
4
|
from
concurrent
import
futures
import
time
_ONE_DAY_IN_SECONDS
=
60
*
60
*
24
|
In Server, is to achieve the service, in accordance with the msg.proto
definition of service here need to write a class MsgServicer
, previously defined class needs to implement GetMsg
.
1
2
3
4
5
|
class
MsgServicer(msg_pb2_grpc.MsgServiceServicer):
def
GetMsg(
self
, request, context):
print
(
"Received name: %s"
%
request.name)
return
msg_pb2.MsgResponse(msg
=
'Hello, %s!'
%
request.name)
|
GetMsg request is received request
, the msg.proto
defined name
is request.name
then designed in GetMsg msg.proto
defined MsgResponse
.
After the realization of the part to start the service.
1
2
3
4
5
6
7
8
9
10
|
def
serve():
server
=
grpc.server(futures.ThreadPoolExecutor(max_workers
=
10
))
msg_pb2_grpc.add_MsgServiceServicer_to_server(MsgServicer(), server)
server.add_insecure_port(
'[::]:50051'
)
server.start()
try
:
while
True
:
time.sleep(_ONE_DAY_IN_SECONDS)
except
KeyboardInterrupt:
server.stop(
0
)
|
By concurrency library, the server into multiple processes in operation.
Complete msg_server.py
code is as follows
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
import
grpc
import
msg_pb2
import
msg_pb2_grpc
from
concurrent
import
futures
import
time
_ONE_DAY_IN_SECONDS
=
60
*
60
*
24
class
MsgServicer(msg_pb2_grpc.MsgServiceServicer):
def
GetMsg(
self
, request, context):
print
(
"Received name: %s"
%
request.name)
return
msg_pb2.MsgResponse(msg
=
'Hello, %s!'
%
request.name)
def
serve():
server
=
grpc.server(futures.ThreadPoolExecutor(max_workers
=
10
))
msg_pb2_grpc.add_MsgServiceServicer_to_server(MsgServicer(), server)
server.add_insecure_port(
'[::]:50051'
)
server.start()
try
:
while
True
:
time.sleep(_ONE_DAY_IN_SECONDS)
except
KeyboardInterrupt:
server.stop(
0
)
if
__name__
=
=
'__main__'
:
serve()
|
创建客户端
客户端相对简单一些,这里我写了一个简单的客户端。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import
grpc
import
msg_pb2
import
msg_pb2_grpc
def
run():
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
# used in circumstances in which the with statement does not fit the needs
# of the code.
with grpc.insecure_channel(
'localhost:50051'
) as channel:
stub
=
msg_pb2_grpc.MsgServiceStub(channel)
response
=
stub.GetMsg(msg_pb2.MsgRequest(name
=
'world'
))
print
(
"Client received: "
+
response.msg)
if
__name__
=
=
'__main__'
:
run()
|
使用 grpc.insecure_channel('localhost:50051')
进行连接 服务端, 接着在这个 channel
上创建 stub
, 在 msg_pb2_grpc
里可以找到 MsgServiceStub
这个类相关信息。这个 stub
可以调用远程的 GetMsg
函数。 MsgRequest
中的 name
即 msg.proto
中定义的数据。在回应里可以得到 msg.proto
中定义的 msg
。
运行
首先运行 python msg_server.py
启动服务端,接着运行 python msg_client.py
机会看到客户端接收到了服务端传来的消息。以上就是一个简单的 RPC 的使用。
总结
这里只是简单的用了一下 gRPC,关于另外三种模式,还在摸索。比起gRPC,我感觉简单 RestFul 更讨我喜欢。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。