标准链接:SOME/IP(Scalable service-Oriented MiddlewarE over IP)。

1.2 Applicability of the protocol

SOME/IP shall be used for inter-ECU Client/Server Serialization.


NOTE

SOME/IP协议是为跨主机的Server/Client SOA架构设计的,包括对应的服务发现协议SOME/IP-SD也是只对跨主机的服务发现进行了规定,对主机内的Server/Client通信方式、服务发现都没有定义


4 Protocol Specification

Alt text
Server/Client 交互模式;图片来源:vsomeip
  • Server与Client之间通过TCP/UDP直接建立链接通信
  • 每个Server可以同时与多个Client建立连接
  • Server通过[sourceIP, sourcePort, dstIP, dstPort, Protocol]五元组确定Client,每个Client可以与Server以TCP和UDP建立两个通道
  • Client负责发起所有TCP链接;Client负责将TCP链接的随机端口号和UDP的端口号发送给Server
  • Server负责主动通过TCP和UDP发送数据给Client
  • Server收到eventgroup的订阅后,就会将event数据主动通过已经建立的TCP或者已知的UDP端口号发给Client
    • Server发送的Client地址是在SubscribeEventGroup服务发现消息中由Client告知Server的
  • Server收到method的Request请求,处理请求,原路通过通信链接返回结果
  • Server没有Client的概念,它只知道有通信连接和订阅信息
    • 从Server的角度看,一个Server,即一个Service Instance,对外监听了两个传输层端口(也可以只监听一个),一个TCP端口,用于接收Client的连接请求;一个UDP端口,用于向Client的UDP端口发送数据
    • Server中的每个event,method只能选择TCP或者UDP通道(SOME/IP-SD 5.1.2.6)

NOTE

  • 具体的实现中Server/Client可以是不同的实体,例如在vsomeip中,一个vsomeip的application类中可以offer多个、request多个服务的实例
  • 协议只规定服务相关的概念,以及与底层传输层TCP,UDP的绑定关系,具体的实现可以不同;但是都需要对TCP,UDP链接进行管理


Server提供的Service由events、methods、fields组成:

  • event:Client订阅event,Server接收到订阅后,当条件满足会主动将event群发给订阅方;Client只能通过eventgroup的形式订阅event;一个eventgroup可以包含一个或者多个当前Service下的event

  • method:Client向Server发起Request,包含参数;Server收到Request后,接收参数,执行相关逻辑,得到返回结果,将返回结果以Response的形式返回给Client

  • field:event和method的组合。包含一个值,当这个值满足某些条件时Server群发该值给所有订阅者(event);这个值可以被set,Client可以调用setter方法设定这个值(method);也可以通过getter方法获取这个值(method)

4.1 Specification of SOME/IP Message Format (Serialization)

4.1.2 Header

4.1.2.1 Message ID [32 Bit]

  • 消息ID全局唯一,唯一的确定一个event或者method
  • 由两部分组成,分别占[16 bits]:
    • Service ID:所属的service ID
    • Method ID:这里Method ID可以是服务内部的method或者event的ID。

NOTE

注意没有Instance ID


4.1.2.4 Request ID [32 Bit]

这个字段跟method,field中的setter,getter(特殊的methods)相关,用于在client所在的机器上唯一的确定当前client的一次method的调用:

  • 这个字段只有在client的机器上才有意义,server不关心这个字段,server只是将该字段拷贝到response消息头中
  • client与server建立TCP/UDP连接后,每一个method都只能在一个通信连接上通信,那么在client这一侧,可能有多个调用方同时在这个连接上发送method请求;在server端,它不关心这个是谁的请求,它只是负责处理这个请求并将结果从收到请求的TCP/UDP链接发送出去;在client这一侧,则需要Request ID来区分收到的来自server的回复是哪一个请求的,这样才能把收到的回复结果放入相应的promise

这个ID由两部分组成,分别占[16 bits]:

  • Client ID [16 Bits]:这个Client ID不是当前server/client服务中的client,而是服务client中的使用方
    • 服务client可以理解为一个TCP/UDP链接通道;Client ID中的client可以理解为向这个TCP/UDP链接发送的一个method请求message的唯一标识符;这个标识符用于把收到的server的response与一次请求唯一对应起来
    • 每一个服务client下的每一个method(即每一个Message ID),都有自己独立的Client ID范围:Client ID唯一性的适用范围是Message ID
  • Session ID [16 Bits]:当前Client ID下当前method请求消息的计数器

NOTE

这里Client ID不是与Service ID对应的Client一方的ID,而是Client的一个用户的ID


4.2 Specification of SOME/IP Protocol

4.2.1 Transport Protocol Bindings

[PRS_SOMEIP_00138] If a server runs different instances of the same service, messages belonging to different service instances shall be mapped to the service instance by the transport protocol port on the server side.c(RS_SOMEIP_00015)

  • SOME/IP支持TCP或者UDP传输层协议
  • 如果一个Machine上同时提供多个同一个Service ID的不同Instance,则这些Instance必须被绑定到不同的Port口,无论是TCP还是UDP,详细原因分析看4.2.1.3
  • 一个Service Instance可以使用的传输层通信方式:
    • TCP单播
    • UDP单播
    • UDP组播

NOTE

这三个Port口是可以同时存在的,但是每一个最多只能有一个;对于服务下面的Event或者Method,只能同时对应一个TCP单播或者UDP单播,不能同时使用两个,这点在SOME/IP-SD 5.1.2.6中有规定


4.2.1.1 UDP Binding

[PRS_SOMEIP_00943] The client and server shall use a single UDP unicast connection for all methods, events, and notifications of a Service-Instance which are configured to be communicated using UDP unicast.c(RS_SOMEIP_00010)

server和client之间一旦建立了TCP/UDP的通道(UDP没有connection,但是此处我们认为相互发现后即是链接),TCP通道负责当前服务下所有配置为使用TCP的event,method,field;UDP通道负责当前服务下所有配置为使用UDP的event,method,field

[PRS_SOMEIP_00942] The client and server may use a single UDP multicast address per each Service-Instance which are configured to be communicated using UDP multicast.c(RS_SOMEIP_00010)

如果server/client之间配置了UDP组播通信,则所有的配置为UDP通信方式的event,method,field都可能通过这个组播地址通信, 在SOME/IP-SD中:

[PRS_SOMEIPSD_00134] Unicast/Multicast switching for event and notification event transmission via UDP dFor events and notification events which are configured to be transmitted via UDP (see [PRS_SOMEIPSD_00802]) SOME/IP-SD shall support automated switching from unicast to multicast communication if a configured threshold of the numbers of subscribers was reached.c(RS_SOMEIPSD_00025, RS_-SOMEIPSD_00016)

4.2.1.2 TCP Binding

[PRS_SOMEIP_00707] The client and server shall use a single TCP connection for all methods, events, and notifications of a Service-Instance which are configured to be communicated using TCP.c(RS_SOMEIP_00010)

server和client之间一旦建立了TCP/UDP的通道(UDP没有connection,但是此处我们认为相互发现后即是链接),TCP通道负责当前服务下所有配置为使用TCP的event,method,field;UDP通道负责当前服务下所有配置为使用UDP的event,method,field

在使用TCP传输层协议时,必须关闭Nagle算法,保证每次数据发送都必须马上打包成一个TCP segment发送出去,目的是保证消息消息实时性。

Nagle算法将多个TCP发送积累成一个大的TCP segment发送的算法,目的是提高TCP数据包的payload比例;因为一个TCP报文的头部占40-Byte,如果单个segment的payload过小,则发送的数据大部分都是头部信息,降低了报文的利用率,增加了线上阻塞的风险

TCP的链接发起、重连、关闭都是由client端决定的

  • 当server端调用了StopOfferService接口停止服务后,不能自行终断TCP链接,而应该是client端来操作,否则client端会进行重连,造成资源浪费

4.2.1.3 Multiple Service-Instances

  • 首先一个机器上,可以针对同一个Service提供多个不同的Service Instance,即服务的实例
  • 每一个Service Instance在一个Service ID下有一个全局唯一的Instance ID
  • 已知SOME/IP的消息头是不包含Service Instance ID信息的(SOME/IP-SD的消息中是包含Instance ID信息的)
  • 以上就会导致一个问题:client如何通过SOME/IP消息头来判断这个消息来自同一个机器上的哪一个Instance

无论是UDP还是TCP都有一个(srcIP, srcPort, dstIP, dstPort)的tuple来表示一个通信链接:

  • 不同机器上的服务实例,无论是同一个服务还是不同的服务,都可以通过通信链接来区分不同的Instance
  • 同一个机器上的不同的Service,可以通过其唯一的Service ID来区分
  • 同一个机器上的相同的Service,因为它们有相同的Service ID,而且SOME/IP消息头不包含Instance ID的信息,只能通过通信链接来区分不同的Instance;从client的视角来看srcIP, dstIP是不能变动的,那么能区分的就只有srcPort或者dstPort,而Instance ID是由服务的提供方,即server侧定义的,所以区分也自然应该由server端来区分:
    • 同一个Host上相同的Service的不同Instance需要绑定到不同的Port端口

4.2.1.4 Transporting large SOME/IP messages of UDP (SOME/IP-TP)

针对一个UDP报文放不下的数据,SOME/IP使用SOME/IP-TP(SOME/IP Transport Protocol)来分成多个UDP报文发送,基本的原理就是每一个分割后的UDP报文都自带一个Session ID接收端通过Session ID来进行组装。SOME/IP标准的建议是能使用UDP的地方尽量使用UDP,只有在传输很大的数据,且没有严格的延迟要求的情况下才使用TCP

4.2.2 Request/Response Communication

  • 所有Request的参数必须按照在函数调用中的实际参数位置顺序进行序列化

4.2.3 Fire&Forget Communication

  • 与普通Request/Response的区别在与不会等待Response

Fire&Forget不是返回值为void 的特殊情况,当然Fire&Forget返回值类型是void,但是与普通Request/Response返回值是void不同,Fire/Forget不会等待,所以无法确定,其请求的任务是否执行完毕。但是普通的返回void的情况下,虽然返回值是void,但是可以通过std::futureget()方法来判断服务方是否已经执行完毕,这种情况往往需要服务方发送完成的标志位给到请求方。而Fire&Forget情况下,服务提供方是不会发送任何回复给请求方的,这也是为什么Fire&Forget的请求永远不会返回错误码。

4.2.4 Notification Events

[PRS_SOMEIP_00930] When more than one subscribed client on the same ECU exists, the system shall handle the replication of notifications in order to save transmissions on the communication medium.c(RS_SOMEIP_00042) This is especially important, when notifications are transported using multicast messages.

AUTOSAR要求当一个client机器上有多个订阅同一个服务ID的Client时,实现上需要考虑降低网络流量,这其实确定了SOME/IP的实现往往需要一个中心节点。只有通过这个中心节点,做统一的收发管理,才能最大程度的优化网络流量。

4.2.4.1 Strategy for sending notifications

订阅发送的三种模式:

  • 周期发送
  • 事件触发发送
  • 值变化超过某个范围发送

4.2.5 Fields

Fields是Events和Methods的融合体,具体表现在:

  • 一个Fields需要至少包含一个getter,一个setter,一个notifier
  • gettersetter,本质就是Methods
  • notifier,本质就是Event

6 Protocol usage and guidelines

6.1 Choosing the transport protocol

SOME/IP的传输层协议是具体到一个消息的:

  • 每一个Event,Method等都可以配置自己的传输层协议

在UDP和TCP的选择上,建议如下:

  • 1400Bytes,且在错误发生时没有严格实时性要求的,使用TCP

  • 如果在错误发生时实时性要求<100ms,使用UDP
  • 如果错误发生时实时性要求<100ms,且消息>1400 Bytes,使用SOME/IP-TP