场景: 用户乘坐无人出租车过程中,可能临时需要切换目的地,用户可以通过车机系统完成修改,路径规划模块需要根据新的目的地信息重新规划路径,并反馈修正后的结果给用户,那么用户的修正请求数据与修正结果是如何被传输的呢?
上述场景下便可以使用服务通信实现数据传输。
概念
以请求响应的方式实现不同节点之间数据交互的通信模式。
作用
用于偶然的、对实时性有要求、有一定逻辑处理需求的数据传输场景。
需求
客户端发送请求提交两个整型数字,服务端处理请求提取两个数字求和,并将结果响应回客户端。
流程
1.编写消息载体(protobuf文件)并配置;
2.编写服务端配置;
3.编写客户端配置;
4.编译执行。
准备
在 demo_base_proto 目录下,新建文件 addints.proto,内容如下:
syntax = "proto2";
package apollo.cyber.demo_basee_proto;
message AddInts_Request {
required int64 num1 = 1;
required int64 num2 = 2;
}
message AddInts_Reponse {
required int64 sum = 1;
}
上述文件中,包含两种消息类型,AddInts_Request 是用于客户端向服务端发送请求的数据类型,AddInts_Response 是用于服务端向客户端发送响应的数据类型。
BUILD 文件添加如下内容:
proto_library(
name="addints_proto",
srcs=["addints.proto"]
)
cc_proto_library(
name = "addints_cc",
deps = [":addints_proto"],
)
py_proto_library(
name = "addints_py",
deps = [":addints_proto"]
)
验证文件编写是否正确,先编译:
bazel build cyber/demo_base_proto/...
C++ 实现
1.服务端实现
demo_cc 目录下新建 C++ 文件 demo03_server.cc,输入如下内容:
BUILD文件:
cc_binary(
name="demo03_server",
srcs=["demo03_server.cc"],
deps=[
"//cyber",
"//cyber/demo_base_proto:addints_cc"
]
)
2.客户端实现
在 demo_cc 目录下新建 C++ 文件 demo04_client.cc,输入如下内容:
#include "cyber/cyber.h"
#include "cyber/demo_base_proto/addints.pb.h"
using apollo::cyber::demo_base_proto::AddInts_Request;
using apollo::cyber::demo_base_proto::AddInts_Reponse;
int main(int argc,char const *argv[]){
apollo::cyber::Init(argv[0]);
if(3 != argc){
AINFO <<"请提交2个整型参数。。。";
return 1;
}
auto client_node = apollo::cyber::CreateNode("addIntsClient_node");
auto client = client_node->CreateClient<AddInts_Request, AddInts_Reponse>("addints");
auto req = std::make_shared<AddInts_Request>();
req->set_num1(atoll(argv[1]));
req->set_num2(atoll(argv[2]));
AINFO <<"请求数据为 num1: " << req->num1() << " and num2: "<<req->num2();
auto reponse = client -> SendRequest(req);
AINFO<<"reponse -->sum = "<< reponse ->sum();
apollo::cyber::WaitForShutdown();
return 0;
}
BUILD文件:
cc_binary(
name="demo04_client",
srcs=["demo04_client.cc"],
deps=[
"//cyber",
"//cyber/demo_base_proto:addints_cc"
]
)
3.执行
python 实现
1.服务端实现
demo_py 目录下新建 python 文件 demo03_server_py.py,输入:
#!/usr/bin/env python3
from cyber.python.cyber_py3 import cyber
from cyber.demo_base_proto.addints_pb2 import AddInts_Request
from cyber.demo_base_proto.addints_pb2 import AddInts_Reponse
def cb(req):
num1 = req.num1
num2 = req.num2
print("num1: %d, num2: %d"%(num1,num2))
sum = num1 + num2
response = AddInts_Reponse()
response.sum = sum
return response
if __name__ == "__main__":
cyber.init()
print("server------")
server_node = cyber.Node("addIntsServer_node_py")
server = server_node.create_service("addints", AddInts_Request,AddInts_Reponse, cb)
server_node.spin()
cyber.shutdown()
BUILD 文件
py_binary(
name = "demo03_server_py",
srcs = ["demo03_server_py.py"],
deps = [
"//cyber/python/cyber_py3:cyber",
"//cyber/demo_base_proto:addints_py"
],
)
2.客户端实现
demo_py 目录下新建 python 文件 demo03_client_py.py,输入:
#!/usr/bin/env python3
from cyber.python.cyber_py3 import cyber
from cyber.demo_base_proto.addints_pb2 import AddInts_Request
from cyber.demo_base_proto.addints_pb2 import AddInts_Reponse
import sys
if __name__ == "__main__":
if len(sys.argv) != 3:
print("input two numbers:")
sys.exit(1)
cyber.init()
print("client------")
client_node = cyber.Node("client_node_py")
client = client_node.create_client("addints", AddInts_Request,AddInts_Reponse)
req = AddInts_Request()
req.num1 = int(sys.argv[1])
req.num2 = int(sys.argv[2])
response = client.send_request(req)
print("reponse sum = %d"%response.sum)
cyber.shutdown()
BUILD 文件
py_binary(
name = "demo04_client_py",
srcs = ["demo04_client_py.py"],
deps = [
"//cyber/python/cyber_py3:cyber",
"//cyber/demo_base_proto:addints_py"
],
)