当前位置:   article > 正文

自动驾驶(八十八)---------通讯之SOMEIP

自动驾驶(八十八)---------通讯之SOMEIP

1. 什么是SOME/IP

        服务导向架构(SOA,Service-Oriented Architecture)是一种设计软件系统的方法,强调通过可重用的服务来实现系统的松散耦合。每个服务是独立的功能单元,可以被不同的应用程序使用。这些服务通过标准化的接口和协议进行通信和数据交换。其特点是:

  1. 松散耦合:服务之间是独立的,减少了组件之间的依赖性,便于系统的扩展和维护。
  2. 可重用性:服务可以被多个应用程序重复使用,提高了代码的重用性和开发效率。
  3. 互操作性:基于标准化的接口和协议(如SOAP、REST、SOME/IP等),不同平台和技术的系统可以相互通信。
  4. 分布式:服务可以部署在不同的物理位置和网络环境中,通过网络进行通信。
  5. 灵活性:可以根据需求动态组合和配置服务,适应不同的业务需求。
  6. 可维护性:独立的服务可以单独开发、测试和部署,便于系统的维护和升级。

        作为SOA基于服务的软件架构,通讯方式自然选择网络层的协议进行通信比较好,这样方便进行SOA的动态配置,支持服务的动态发现和调用,因此一般选SOMEIP作为SOA的通讯方式。

        SOME/IP是一种基于IP的通信协议,实现分布式服务之间的通信和数据传输。其特点是:

  1. 标准化:SOME/IP是为汽车电子系统设计的标准化通信协议,支持服务发现、方法调用和事件通知,符合SOA的标准化要求。

  2. 高性能:SOME/IP设计用于满足汽车电子系统的实时性和高带宽需求,具有高效的数据传输能力。

  3. 服务导向:SOME/IP支持服务导向的通信模式,便于实现SOA架构中的服务发现和动态配置。

  4. 可靠性:SOME/IP具有强大的错误处理和恢复机制,确保通信的可靠性和稳定性。

  5. 扩展性:基于IP协议的SOME/IP可以方便地扩展和集成到不同的网络和系统中,适应不断变化的业务需求。

2. SOME/IP的原理和组件

        SOME/IP作为一种应用层协议,运行在TCP/IP协议栈之上,SOME/IP协议定义了服务发现、方法调用和事件通知等机制,传输层使用TCP或UDP协议进行数据传输。

        

工作流程如下:

        1. 服务注册,服务端在启动时,通过广播或多播方式向网络中的其他设备宣布自己的服务,并注册到服务发现模块。

        2. 服务发现,客户端在需要使用某个服务时,通过广播或多播方式发送服务发现请求,寻找可用的服务。      

  3. 方法调用,客户端发现服务后,发送请求消息,调用服务端提供的方法。服务端接收到请求后,处理请求并返回响应消息。

        4. 事件通知,服务端可以发布事件,通知客户端某些状态或数据的变化。客户端订阅特定服务的事件,接收事件消息。

        5. 高效的数据封装,SOME/IP定义了消息的封装格式,包括消息头和消息负载,确保数据能够高效传输。消息头包含服务ID、实例ID、方法ID等信息,便于消息的解析和处理。

3. 实例代码

        以下是一个简单的SOME/IP客户端和服务端示例,展示了基本的服务发现、方法调用和事件通知过程。

        在SOME/IP中,IP地址和端口通常通过配置文件进行管理。以下是一个示例配置文件vsomeip.json,其中包含了IP地址和端口的设置:        

  1. {
  2. "unicast": "192.168.0.100", // 本地IP地址
  3. "netmask": "255.255.255.0", // 子网掩码
  4. "gateway": "192.168.0.1", // 网关
  5. "applications": [
  6. {
  7. "name": "Service", // 应用名称
  8. "id": "0x1234", // 应用ID
  9. "instance": "0x5678", // 实例ID
  10. "service": "0x4321", // 服务ID
  11. "eventgroups": [
  12. {
  13. "group_id": "0x00", // 事件组ID
  14. "events": [
  15. {
  16. "event_id": "0x0421" // 事件ID
  17. }
  18. ]
  19. }
  20. ],
  21. "port": 30490, // 服务端口
  22. "protocol": "UDP" // 传输协议
  23. }
  24. ],
  25. "routing": {
  26. "protocol": "UDP", // 路由协议
  27. "port": 30509, // 路由端口
  28. "routing_manager": true // 是否启用路由管理器
  29. }
  30. }

        服务端代码:

  1. #include <vsomeip/vsomeip.hpp>
  2. #include <iostream>
  3. class SomeIPServer {
  4. public:
  5. SomeIPServer() : app_(vsomeip::runtime::get()->create_application("Service")) {}
  6. bool init() {
  7. app_->init("vsomeip.json"); // 初始化时加载配置文件
  8. app_->register_message_handler(SERVICE_ID, INSTANCE_ID, METHOD_ID,
  9. std::bind(&SomeIPServer::on_message, this, std::placeholders::_1));
  10. app_->register_state_handler(
  11. std::bind(&SomeIPServer::on_state, this, std::placeholders::_1));
  12. app_->offer_service(SERVICE_ID, INSTANCE_ID);
  13. return true;
  14. }
  15. void start() {
  16. app_->start();
  17. }
  18. private:
  19. void on_message(const std::shared_ptr<vsomeip::message> &msg) {
  20. std::shared_ptr<vsomeip::payload> payload = msg->get_payload();
  21. std::string message(payload->get_data(), payload->get_data() + payload->get_length());
  22. std::cout << "Received message: " << message << std::endl;
  23. // Sending a response
  24. std::shared_ptr<vsomeip::message> response = vsomeip::runtime::get()->create_response(msg);
  25. std::string response_message = "Hello from the server!";
  26. std::shared_ptr<vsomeip::payload> response_payload = vsomeip::runtime::get()->create_payload();
  27. response_payload->set_data(reinterpret_cast<const vsomeip::byte_t *>(response_message.data()), response_message.size());
  28. response->set_payload(response_payload);
  29. app_->send(response);
  30. }
  31. void on_state(vsomeip::state_type_e state) {
  32. if (state == vsomeip::state_type_e::ST_REGISTERED) {
  33. app_->offer_service(SERVICE_ID, INSTANCE_ID);
  34. }
  35. }
  36. std::shared_ptr<vsomeip::application> app_;
  37. const vsomeip::service_t SERVICE_ID = 0x4321;
  38. const vsomeip::instance_t INSTANCE_ID = 0x5678;
  39. const vsomeip::method_t METHOD_ID = 0x0421;
  40. };
  41. int main() {
  42. SomeIPServer server;
  43. if (server.init()) {
  44. server.start();
  45. }
  46. return 0;
  47. }

        客户端代码实例:

  1. #include <vsomeip/vsomeip.hpp>
  2. #include <iostream>
  3. class SomeIPClient {
  4. public:
  5. SomeIPClient() : app_(vsomeip::runtime::get()->create_application("Client")) {}
  6. bool init() {
  7. app_->init("vsomeip.json"); // 初始化时加载配置文件
  8. app_->register_message_handler(SERVICE_ID, INSTANCE_ID, METHOD_ID,
  9. std::bind(&SomeIPClient::on_message, this, std::placeholders::_1));
  10. app_->register_state_handler(
  11. std::bind(&SomeIPClient::on_state, this, std::placeholders::_1));
  12. return true;
  13. }
  14. void start() {
  15. app_->start();
  16. }
  17. void send_request() {
  18. std::shared_ptr<vsomeip::message> request = vsomeip::runtime::get()->create_request();
  19. request->set_service(SERVICE_ID);
  20. request->set_instance(INSTANCE_ID);
  21. request->set_method(METHOD_ID);
  22. std::string request_message = "Hello from the client!";
  23. std::shared_ptr<vsomeip::payload> request_payload = vsomeip::runtime::get()->create_payload();
  24. request_payload->set_data(reinterpret_cast<const vsomeip::byte_t *>(request_message.data()), request_message.size());
  25. request->set_payload(request_payload);
  26. app_->send(request);
  27. }
  28. private:
  29. void on_message(const std::shared_ptr<vsomeip::message> &msg) {
  30. std::shared_ptr<vsomeip::payload> payload = msg->get_payload();
  31. std::string message(payload->get_data(), payload->get_data() + payload->get_length());
  32. std::cout << "Received response: " << message << std::endl;
  33. }
  34. void on_state(vsomeip::state_type_e state) {
  35. if (state == vsomeip::state_type_e::ST_REGISTERED) {
  36. send_request();
  37. }
  38. }
  39. std::shared_ptr<vsomeip::application> app_;
  40. const vsomeip::service_t SERVICE_ID = 0x4321;
  41. const vsomeip::instance_t INSTANCE_ID = 0x5678;
  42. const vsomeip::method_t METHOD_ID = 0x0421;
  43. };
  44. int main() {
  45. SomeIPClient client;
  46. if (client.init()) {
  47. client.start();
  48. }
  49. return 0;
  50. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/899848
推荐阅读
相关标签
  

闽ICP备14008679号