SOME/IP-SD -- 协议英文原文讲解8
前言
SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块:
1. SOME/IP协议讲解
2. SOME/IP-SD协议讲解
3. python/C++举例调试讲解
5.1.4.4 State Machines
[PRS_SOMEIPSD_00433]
Upstream requirements: RS_SOMEIPSD_00025
In this section the state machines of the client and server are shown.
这章节展示server和client之间的状态机
-- 用来理解之前讲的规范
5.1.4.4 State Machines
[PRS_SOMEIPSD_00433]
Upstream requirements: RS_SOMEIPSD_00025
In this section the state machines of the client and server are shown.
这章节展示server和client之间的状态机
-- 用来理解之前讲的规范 --- 主要用来做编程指导
SOME/IP Service State Machine Server is described as follows:
States inside SD Server State Machine(Service) are defined as follows:
• SD Server State Machine(Service)
– Not Ready
– Ready
∗ Initial Wait Phase
· Timer Set
∗ Repetition Phase
· Timer Set
∗ Main Phase
· Timer Set
Initial entry points of SD Server State Machine(Service) are inside the following states:
• SD Server State Machine(Service)
– Ready
∗ Initial Wait Phase
∗ Repetition Phase
∗ Main Phase
Transitions inside SD Server State Machine(Service) are defined as follows:
FROM entry point SD Server State Machine(Service)
TO Not Ready
WITH [ifstatus!=up_and_configured or service-status==down]
FROM entry point SD Server State Machine(Service)
TO Not Ready
WITH [ifstatus==up_and_configured or service-status==up]
FROM Not Ready
TO Ready
WITH if-status-changed() or service-status-changed() [ifstatus==up_and_configured and service-status==up]
FROM Ready
TO Not Ready
WITH if-status-changed [ifstatus!=up_and_configured] /clearAllTimers()
FROM Ready
TO Not Ready
WITH service-status==down /clearAllTimers()
send(StopOfferService)
FROM TimerSet
OF Initial Wait Phase
TO Repetition Phase
WITH Timer expired /send(OfferService)
**SOME/IP 服务发现(SD)服务器状态机**定义了服务在可用性和与客户端通信方面的行为。以下是基于你描述的状态机的详细解释:
---
### **SD 服务器状态机(服务)中的状态**
1. **未就绪(Not Ready)**
- 服务不可用,无法进行通信。
- 进入此状态的条件:
- 接口状态不是 `up_and_configured`(未启动并配置)。
- 服务状态为 `down`(关闭)。
2. **就绪(Ready)**
- 服务可用,可以与客户端通信。
- 包含三个阶段:
- **初始等待阶段(Initial Wait Phase)**:
- 设置一个计时器,延迟服务的广告启动。
- **重复阶段(Repetition Phase)**:
- 服务周期性地广播其可用性。
- **主阶段(Main Phase)**:
- 服务持续运行,等待客户端请求。
---
### **SD 服务器状态机(服务)的初始入口点**
- 状态机的初始入口点位于以下状态:
- **就绪(Ready)**:
- 初始等待阶段(Initial Wait Phase)。
- 重复阶段(Repetition Phase)。
- 主阶段(Main Phase)。
---
### **SD 服务器状态机(服务)中的状态转换**
1. **从入口点到未就绪(Not Ready)**:
- 条件:`ifstatus != up_and_configured` 或 `service-status == down`。
- 动作:无。
2. **从入口点到未就绪(Not Ready)**:
- 条件:`ifstatus == up_and_configured` 或 `service-status == up`。
- 动作:无。
3. **从未就绪(Not Ready)到就绪(Ready)**:
- 条件:`if-status-changed()` 或 `service-status-changed()`,且 `ifstatus == up_and_configured` 且 `service-status == up`。
- 动作:无。
4. **从就绪(Ready)到未就绪(Not Ready)**:
- 条件:`if-status-changed` 且 `ifstatus != up_and_configured`。
- 动作:清除所有计时器(`clearAllTimers()`)。
5. **从就绪(Ready)到未就绪(Not Ready)**:
- 条件:`service-status == down`。
- 动作:清除所有计时器(`clearAllTimers()`)并发送 `StopOfferService` 消息。
6. **从初始等待阶段(Initial Wait Phase)的计时器设置(TimerSet)到重复阶段(Repetition Phase)**:
- 条件:计时器到期(`Timer expired`)。
- 动作:发送 `OfferService` 消息。
FROM TimerSet
OF Repetition Phase
TO TimerSet
OF Repetition Phase
WITH receive(FindService) /waitAndSend(OfferService) ResetTimer()
FROM TimerSet
OF Repetition Phase
TO TimerSet
OF Repetition Phase
WITH Timer expired [run<REPETITIONS_MAX] /send(OfferService)
run++ setTimer((2ˆrun)*REPETITIONS_BASE_DELAY
FROM TimerSet
OF Repetition Phase
TO Main Phase
WITH Timer expired [run==REPETITIONS_MAX]
FROM entry point Ready
TO Initial Wait Phase
FROM entry point Initial Wait Phase
TO Timer Set
OF Initial Wait Phase
WITH SetTimerInRange(INITIAL_DELAY_MIN,INITIAL_DELAY_MAX)
FROM entry point Repetition Phase
TO Timer Set
OF Repetition Phase
WITH [REPETITIONS_MAX>0] /run=0 setTimer((2ˆrun)*REPETITIONS_BASE_DELAY)
FROM entry point Repetition Phase
TO Main Phase
WITH [REPETITIONS_MAX==0]
FROM entry point Main Phase
TO Timer Set
OF Main Phase
WITH /setTimer(CYCLIC_ANNOUNCE_DELAY) send(OfferService)
FROM Timer Set
OF Main Phase
TO Timer Set
OF Main Phase
WITH Timer expired /setTimer(CYCLIC_ANNOUNCE_DELAY)
send(OfferService)
FROM Timer Set
OF Main Phase
TO Timer Set
OF Main Phase
WITH receive(FindService) /waitAndSend(OfferService) resetTimer()
这段描述是关于 **SOME/IP 服务发现(SD)服务器状态机** 中 **重复阶段(Repetition Phase)** 和 **主阶段(Main Phase)** 的状态转换规则。以下是逐条解释:
---
### **1. 重复阶段(Repetition Phase)的状态转换**
#### **(1) 从重复阶段的 TimerSet 到重复阶段的 TimerSet**
- **条件**:接收到 `FindService` 消息。
- **动作**:
- 等待并发送 `OfferService` 消息(`waitAndSend(OfferService)`)。
- 重置计时器(`ResetTimer()`)。
- **说明**:当客户端发送 `FindService` 请求时,服务器会立即响应 `OfferService`,并重置计时器以继续周期性广播。
#### **(2) 从重复阶段的 TimerSet 到重复阶段的 TimerSet**
- **条件**:计时器到期(`Timer expired`),且当前重复次数 `run` 小于最大重复次数 `REPETITIONS_MAX`。
- **动作**:
- 发送 `OfferService` 消息。
- 增加重复次数 `run++`。
- 设置新的计时器,延迟时间为 `(2^run) * REPETITIONS_BASE_DELAY`。
- **说明**:在重复阶段,服务器会周期性地广播 `OfferService` 消息,每次广播的间隔时间会指数级增长(`2^run`),直到达到最大重复次数。
#### **(3) 从重复阶段的 TimerSet 到主阶段(Main Phase)**
- **条件**:计时器到期(`Timer expired`),且当前重复次数 `run` 等于最大重复次数 `REPETITIONS_MAX`。
- **动作**:无。
- **说明**:当达到最大重复次数后,状态机进入主阶段,开始稳定的周期性广播。
---
### **2. 初始入口点的状态转换**
#### **(1) 从入口点 Ready 到初始等待阶段(Initial Wait Phase)**
- **说明**:状态机从就绪状态进入初始等待阶段。
#### **(2) 从初始等待阶段(Initial Wait Phase)到 TimerSet**
- **条件**:设置计时器,延迟时间在 `INITIAL_DELAY_MIN` 和 `INITIAL_DELAY_MAX` 之间随机选择。
- **动作**:设置计时器(`SetTimerInRange(INITIAL_DELAY_MIN, INITIAL_DELAY_MAX)`)。
- **说明**:在初始等待阶段,服务器会随机延迟一段时间,以避免多个服务同时启动导致的网络拥塞。
#### **(3) 从入口点重复阶段(Repetition Phase)到 TimerSet**
- **条件**:最大重复次数 `REPETITIONS_MAX > 0`。
- **动作**:
- 初始化重复次数 `run = 0`。
- 设置计时器,延迟时间为 `(2^run) * REPETITIONS_BASE_DELAY`。
- **说明**:进入重复阶段后,初始化计时器并开始周期性广播。
#### **(4) 从入口点重复阶段(Repetition Phase)到主阶段(Main Phase)**
- **条件**:最大重复次数 `REPETITIONS_MAX == 0`。
- **动作**:无。
- **说明**:如果不需要重复广播,则直接进入主阶段。
---
### **3. 主阶段(Main Phase)的状态转换**
#### **(1) 从入口点主阶段(Main Phase)到 TimerSet**
- **条件**:无。
- **动作**:
- 设置计时器,延迟时间为 `CYCLIC_ANNOUNCE_DELAY`。
- 发送 `OfferService` 消息。
- **说明**:进入主阶段后,服务器会以固定间隔 `CYCLIC_ANNOUNCE_DELAY` 周期性广播 `OfferService` 消息。
#### **(2) 从主阶段的 TimerSet 到 TimerSet**
- **条件**:计时器到期(`Timer expired`)。
- **动作**:
- 设置计时器,延迟时间为 `CYCLIC_ANNOUNCE_DELAY`。
- 发送 `OfferService` 消息。
- **说明**:在主阶段,服务器会持续以固定间隔广播 `OfferService` 消息。
#### **(3) 从主阶段的 TimerSet 到 TimerSet**
- **条件**:接收到 `FindService` 消息。
- **动作**:
- 等待并发送 `OfferService` 消息(`waitAndSend(OfferService)`)。
- 重置计时器(`resetTimer()`)。
- **说明**:当客户端发送 `FindService` 请求时,服务器会立即响应 `OfferService`,并重置计时器以继续周期性广播。

[PRS_SOMEIPSD_00435]
Upstream requirements: RS_SOMEIPSD_00025
SOME/IP Service State Machine Client is described as follows:
States inside SD Client State Machine(Service) are defined as follows:
• SD Client State Machine(Service)
– Not Requested
∗ Service Not Seen
∗ Service Seen
– Requested_but_not_ready
– Main
∗ Service Ready
∗ Stopped
– Searching for Service
∗ Initial Wait Phase
· Timer Set
∗ Repetition Phase
· Timer Set
Initial entry points of SD Client State Machine(Service) are inside the following states:
• SD Client State Machine(Service)
– Not Requested
• Searching for Service
– Initial Wait Phase
– Repetition Phase
Transitions inside SD Client State Machine(Service) are defined as follows:
FROM entry point SD Client State Machine(Service)
TO Not Requested
WITH [Service Not Requestedd]
FROM entry point SD Client State Machine(Service)
TO Requested_but_not_ready
WITH Service Not Requested and ifstatus!=up_and_configured
FROM entry point SD Client State Machine(Service)
TO Searching for Service
WITH Service Requested and ifstatus==up_and_configured
FROM entry point Not Requested TO Service Not Seen
FROM Not Requested TO Requested_but_not_ready
WITH InternalServiceRequest [ifstatus!=up_and_configured]
FROM Service Not Seen
TO Service Seen
WITH receive(OfferService) /setTimer(TTL)
FROM Repetition Phase
TO Stopped
WITH Repetition Expired
FROM Repetition Phase
TO Stopped
WITH receive(StopOfferService)
FROM Stopped
TO Service Not Seen
WITH [ServiceNotRequired]
FROM Service Seen
TO Service Not Seen
WITH if-status-changed() [ifstatus!=up_and_configured]
FROM Service Seen
TO Service Not Seen
WITH Timer expired (TTL)
FROM Repetition Phase
TO Stopped
WITH Repetition Expired
### **1. 客户端状态机中的状态**
1. **未请求(Not Requested)**:
- 客户端尚未请求服务。
- 包含两个子状态:
- **服务未发现(Service Not Seen)**:客户端未收到服务的 `OfferService` 消息。
- **服务已发现(Service Seen)**:客户端收到了服务的 `OfferService` 消息。
2. **已请求但未就绪(Requested_but_not_ready)**:
- 客户端已请求服务,但服务尚未就绪(例如,网络接口未配置完成)。
3. **主状态(Main)**:
- 客户端已请求服务,并且服务已就绪。
- 包含两个子状态:
- **服务就绪(Service Ready)**:服务可用,客户端可以正常使用。
- **服务停止(Stopped)**:服务不可用。
4. **搜索服务(Searching for Service)**:
- 客户端正在主动搜索服务。
- 包含两个阶段:
- **初始等待阶段(Initial Wait Phase)**:设置计时器,延迟搜索。
- **重复阶段(Repetition Phase)**:周期性发送 `FindService` 请求。
---
### **2. 客户端状态机的初始入口点**
- 状态机的初始入口点位于以下状态:
- **未请求(Not Requested)**。
- **搜索服务(Searching for Service)**:
- 初始等待阶段(Initial Wait Phase)。
- 重复阶段(Repetition Phase)。
---
### **3. 客户端状态机中的状态转换**
#### **(1) 从入口点到未请求(Not Requested)**
- **条件**:服务未被请求(`Service Not Requested`)。
- **动作**:无。
#### **(2) 从入口点到已请求但未就绪(Requested_but_not_ready)**
- **条件**:服务未被请求(`Service Not Requested`),且网络接口未配置完成(`ifstatus != up_and_configured`)。
- **动作**:无。
#### **(3) 从入口点到搜索服务(Searching for Service)**
- **条件**:服务已被请求(`Service Requested`),且网络接口已配置完成(`ifstatus == up_and_configured`)。
- **动作**:无。
#### **(4) 从未请求(Not Requested)到服务未发现(Service Not Seen)**
- **说明**:初始状态为服务未发现。
#### **(5) 从未请求(Not Requested)到已请求但未就绪(Requested_but_not_ready)**
- **条件**:客户端内部请求服务(`InternalServiceRequest`),且网络接口未配置完成(`ifstatus != up_and_configured`)。
- **动作**:无。
#### **(6) 从服务未发现(Service Not Seen)到服务已发现(Service Seen)**
- **条件**:接收到服务的 `OfferService` 消息。
- **动作**:设置计时器(`setTimer(TTL)`),用于检查服务的存活时间(TTL)。
#### **(7) 从重复阶段(Repetition Phase)到服务停止(Stopped)**
- **条件**:重复阶段计时器到期(`Repetition Expired`)。
- **动作**:无。
#### **(8) 从重复阶段(Repetition Phase)到服务停止(Stopped)**
- **条件**:接收到服务的 `StopOfferService` 消息。
- **动作**:无。
#### **(9) 从服务停止(Stopped)到服务未发现(Service Not Seen)**
- **条件**:服务不再需要(`ServiceNotRequired`)。
- **动作**:无。
#### **(10) 从服务已发现(Service Seen)到服务未发现(Service Not Seen)**
- **条件**:网络接口状态变化(`if-status-changed()`),且网络接口未配置完成(`ifstatus != up_and_configured`)。
- **动作**:无。
#### **(11) 从服务已发现(Service Seen)到服务未发现(Service Not Seen)**
- **条件**:计时器到期(`Timer expired (TTL)`)。
- **动作**:无。
#### **(12) 从重复阶段(Repetition Phase)到服务停止(Stopped)**
- **条件**:重复阶段计时器到期(`Repetition Expired`)。
- **动作**:无。
---
FROM Service Seen
TO Service Not Seen
WITH receive(StopServiceOffer)
FROM Service Seen
TO Service Seen
FROM Service Seen
TO Service Ready
WITH InternalServiceRequest [ifstatus==up_and_configured]
FROM Service Ready
TO Service Seen
WITH [ServiceNotRequest]
FROM Service Ready
TO Service Ready
WITH receive(OfferService) /resetTimer(TTL)
FROM Service Ready
TO Stopped
WITH receive(StopOfferService) / cancelTimer(TTL)
FROM Stopped
TO Service Ready
WITH receive(OfferService) /resetTimer(TTL)
FROM Service Ready
TO Searching for Service
WITH Timer expired (TTL)
FROM Searching for Service
TO Service Ready
WITH receive(OfferService) /setTimer(TTL)
FROM Searching for Service
TO Requested_but_not_ready
WITH if-status-changed() [ifstatus!=up_and_configured] /cancelTimer(TTL)
FROM Requested_but_not_ready
TO Searching for Service
WITH if-status-changed() [ifstatus!=up_and_configured]
FROM entry point Searching for Service
TO Initial Wait Phase
FROM entry point Initial Wait Phase
TO Timer Set
OF Initial Wait Phase
WITH /setTimerInRange(INITIAL_DELAY_MIN, INITIAL_DELAY_MAX)
FROM Timer Set
OF Initial Wait Phase
TO Repetition Phase
WITH TimerExpired /send(FindService)
FROM entry point Repetition Phase
TO Timer Set
OF Repetition Phase
WITH [REPETITONS_MAX>0] /run=0 setTimer((2ˆrun)*REPETITIONS_BASE_DELAY)
FROM Timer Set
OF Repetition Phase
TO Timer Set
OF Repetition Phase
FROM Not Requested
TO Requested_but_not_ready
WITH InternalServiceRequest [ifstatus!=up_and_configured]
Note: Graphical information of the SOME/IP Service State Machine Client is shown in
Figure 5.17
### **1. 从服务已发现(Service Seen)到服务未发现(Service Not Seen)**
- **条件**:接收到 `StopServiceOffer` 消息。
- **动作**:无。
- **说明**:当客户端收到服务的 `StopServiceOffer` 消息时,表示服务不再可用,客户端将状态切换为“服务未发现”。
---
### **2. 从服务已发现(Service Seen)到服务已发现(Service Seen)**
- **说明**:状态保持不变。
---
### **3. 从服务已发现(Service Seen)到服务就绪(Service Ready)**
- **条件**:客户端内部请求服务(`InternalServiceRequest`),且网络接口已配置完成(`ifstatus == up_and_configured`)。
- **动作**:无。
- **说明**:当客户端请求服务且网络接口已就绪时,状态切换到“服务就绪”。
---
### **4. 从服务就绪(Service Ready)到服务已发现(Service Seen)**
- **条件**:服务不再需要(`ServiceNotRequest`)。
- **动作**:无。
- **说明**:当客户端不再需要服务时,状态切换回“服务已发现”。
---
### **5. 从服务就绪(Service Ready)到服务就绪(Service Ready)**
- **条件**:接收到 `OfferService` 消息。
- **动作**:重置计时器(`resetTimer(TTL)`)。
- **说明**:当客户端收到服务的 `OfferService` 消息时,重置服务的存活时间计时器(TTL)。
---
### **6. 从服务就绪(Service Ready)到服务停止(Stopped)**
- **条件**:接收到 `StopOfferService` 消息。
- **动作**:取消计时器(`cancelTimer(TTL)`)。
- **说明**:当客户端收到 `StopOfferService` 消息时,表示服务停止,客户端取消计时器并切换到“服务停止”状态。
---
### **7. 从服务停止(Stopped)到服务就绪(Service Ready)**
- **条件**:接收到 `OfferService` 消息。
- **动作**:重置计时器(`resetTimer(TTL)`)。
- **说明**:当客户端再次收到 `OfferService` 消息时,重置计时器并切换到“服务就绪”状态。
---
### **8. 从服务就绪(Service Ready)到搜索服务(Searching for Service)**
- **条件**:计时器到期(`Timer expired (TTL)`)。
- **动作**:无。
- **说明**:当服务的存活时间计时器到期时,客户端开始重新搜索服务。
---
### **9. 从搜索服务(Searching for Service)到服务就绪(Service Ready)**
- **条件**:接收到 `OfferService` 消息。
- **动作**:设置计时器(`setTimer(TTL)`)。
- **说明**:当客户端在搜索阶段收到 `OfferService` 消息时,设置计时器并切换到“服务就绪”状态。
---
### **10. 从搜索服务(Searching for Service)到已请求但未就绪(Requested_but_not_ready)**
- **条件**:网络接口状态变化(`if-status-changed()`),且网络接口未配置完成(`ifstatus != up_and_configured`)。
- **动作**:取消计时器(`cancelTimer(TTL)`)。
- **说明**:当网络接口未就绪时,客户端取消搜索并切换到“已请求但未就绪”状态。
---
### **11. 从已请求但未就绪(Requested_but_not_ready)到搜索服务(Searching for Service)**
- **条件**:网络接口状态变化(`if-status-changed()`),且网络接口已配置完成(`ifstatus == up_and_configured`)。
- **动作**:无。
- **说明**:当网络接口恢复就绪时,客户端重新开始搜索服务。
---
### **12. 从入口点搜索服务(Searching for Service)到初始等待阶段(Initial Wait Phase)**
- **说明**:客户端进入搜索服务的初始等待阶段。
---
### **13. 从初始等待阶段(Initial Wait Phase)到 Timer Set**
- **条件**:无。
- **动作**:设置计时器,延迟时间在 `INITIAL_DELAY_MIN` 和 `INITIAL_DELAY_MAX` 之间随机选择(`setTimerInRange(INITIAL_DELAY_MIN, INITIAL_DELAY_MAX)`)。
- **说明**:在初始等待阶段,客户端随机延迟一段时间,以避免多个客户端同时发送请求导致的网络拥塞。
---
### **14. 从 Timer Set(初始等待阶段)到重复阶段(Repetition Phase)**
- **条件**:计时器到期(`TimerExpired`)。
- **动作**:发送 `FindService` 请求。
- **说明**:初始等待阶段结束后,客户端发送 `FindService` 请求并进入重复阶段。
---
### **15. 从入口点重复阶段(Repetition Phase)到 Timer Set**
- **条件**:最大重复次数 `REPETITIONS_MAX > 0`。
- **动作**:
- 初始化重复次数 `run = 0`。
- 设置计时器,延迟时间为 `(2^run) * REPETITIONS_BASE_DELAY`。
- **说明**:进入重复阶段后,客户端以指数级增长的间隔时间周期性发送 `FindService` 请求。
---
### **16. 从 Timer Set(重复阶段)到 Timer Set(重复阶段)**
- **说明**:状态保持不变。
---
### **17. 从未请求(Not Requested)到已请求但未就绪(Requested_but_not_ready)**
- **条件**:客户端内部请求服务(`InternalServiceRequest`),且网络接口未配置完成(`ifstatus != up_and_configured`)。
- **动作**:无。
- **说明**:当客户端请求服务但网络接口未就绪时,切换到“已请求但未就绪”状态。

Note: The most likely assumed cause for a TTL expiry while the client’s state machine resides in state "Service Ready" is the temporary (duration in the order of the
CYCLIC_OFFER_DELAY or smaller) failure of an intermediate link (i.e., a link along
the path from client to server which, however, is not directly connected to the client
ECU and thus this link failure is not perceivable via a change in the ifstatus). Thus,
the specified reaction - namely transition into "Searching for Service" state (and thus
into the initial wait phase) - in case of a TTL expiry is deliberately different from the
specified reactions in case of received StopOfferService entries and detected server
reboots, where a transition into the "Stopped" state takes place. Transiting back into
the "Searching for Service" state in case of TTL expiries caused by temporary intermediate link failures speeds up recovery by approx. a factor of 10 (depending on
the configuration of the INITIAL_DELAY, the REQUEST_RESPONSE_DELAY, and the
CYCLIC_OFFER_DELAY) through the explicit sending of FindService entries by the
client which are answered by OfferService entries of the server (even if the server itself
resides in the main phase).
这段注释解释了 **SOME/IP 服务发现(SD)客户端状态机** 中,当客户端处于 **“服务就绪(Service Ready)”** 状态时,**TTL(Time To Live,存活时间)到期** 的可能原因及其设计意图。以下是详细解释:
---
### **1. TTL 到期的可能原因**
- **中间链路临时故障**:
- 当客户端处于“服务就绪”状态时,TTL 到期的**最可能原因**是客户端与服务器之间的**中间链路发生了临时故障**。
- 这种故障的持续时间通常与 `CYCLIC_OFFER_DELAY`(周期性广播延迟)相当或更短。
- 中间链路故障**不会直接导致客户端感知到网络接口状态变化(`ifstatus` 不变)**,因为故障发生在客户端 ECU(电子控制单元)之外的链路上。
---
### **2. 设计意图:TTL 到期后的状态转换**
- **状态转换**:
- 当 TTL 到期时,客户端会从 **“服务就绪(Service Ready)”** 状态切换到 **“搜索服务(Searching for Service)”** 状态。
- 这种设计是**有意为之**,与以下两种情况不同:
1. **接收到 `StopOfferService` 消息**:客户端会切换到 **“服务停止(Stopped)”** 状态。
2. **检测到服务器重启**:客户端也会切换到 **“服务停止(Stopped)”** 状态。
- **目的**:
- 通过切换到 **“搜索服务”** 状态,客户端会**主动发送 `FindService` 请求**,服务器会立即响应 `OfferService` 消息。
- 这种方式可以**加快服务恢复速度**,大约提高 10 倍(具体取决于 `INITIAL_DELAY`、`REQUEST_RESPONSE_DELAY` 和 `CYCLIC_OFFER_DELAY` 的配置)。
---
### **3. 为什么切换到“搜索服务”状态能加快恢复?**
- **主动发送 `FindService` 请求**:
- 在 **“搜索服务”** 状态下,客户端会主动发送 `FindService` 请求,服务器会立即响应 `OfferService` 消息。
- 这种方式比等待服务器周期性广播 `OfferService` 消息(`CYCLIC_OFFER_DELAY`)更快。
- **避免等待周期性广播**:
- 如果客户端切换到 **“服务停止”** 状态,它需要等待服务器重新广播 `OfferService` 消息,这可能会引入额外的延迟。
---
### **4. 与 `StopOfferService` 和服务器重启的区别**
- **接收到 `StopOfferService` 消息**:
- 表示服务器明确告知服务已停止,客户端应切换到 **“服务停止”** 状态。
- **检测到服务器重启**:
- 表示服务器已重启,客户端应切换到 **“服务停止”** 状态。
- **TTL 到期**:
- 可能是由于中间链路临时故障,客户端应切换到 **“搜索服务”** 状态以快速恢复。
---
### **5. 配置参数的影响**
- **`INITIAL_DELAY`**:初始等待阶段的延迟时间。
- **`REQUEST_RESPONSE_DELAY`**:客户端发送 `FindService` 请求后等待服务器响应的延迟时间。
- **`CYCLIC_OFFER_DELAY`**:服务器周期性广播 `OfferService` 消息的间隔时间。
这些参数的配置会影响服务恢复的速度。通过主动发送 `FindService` 请求,客户端可以绕过 `CYCLIC_OFFER_DELAY` 的等待时间,从而显著加快恢复。
相关文章:
SOME/IP-SD -- 协议英文原文讲解8
前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 5.1.4.4 S…...
【Agent实战】货物上架位置推荐助手(RAG方式+结构化prompt(CoT)+API工具结合ChatGPT4o能力Agent项目实践)
本文原创作者:姚瑞南 AI-agent 大模型运营专家,先后任职于美团、猎聘等中大厂AI训练专家和智能运营专家岗;多年人工智能行业智能产品运营及大模型落地经验,拥有AI外呼方向国家专利与PMP项目管理证书。(转载需经授权) 目录 结论 效果图示 1.prompt 2. API工具封…...
Spring Boot使用线程池创建多线程
在 Spring Boot 2 中,可以使用 Autowired 注入 线程池(ThreadPoolTaskExecutor 或 ExecutorService),从而管理线程的创建和执行。以下是使用 Autowired 方式注入线程池的完整示例。 1. 通过 Autowired 注入 ThreadPoolTaskExecuto…...
PyTorch 深度学习实战(11):强化学习与深度 Q 网络(DQN)
在之前的文章中,我们介绍了神经网络、卷积神经网络(CNN)、循环神经网络(RNN)、Transformer 等多种深度学习模型,并应用于图像分类、文本分类、时间序列预测等任务。本文将介绍强化学习的基本概念࿰…...
在Eclipse 中使用 MyBatis 进行开发,通常需要以下步骤:
在Eclipse 中使用 MyBatis 进行开发,通常需要以下步骤: 1. 创建 Maven 项目 首先,在 Eclipse 中创建一个 Maven 项目。如果你还没有安装 Maven 插件,可以通过 Eclipse Marketplace 安装 Maven 插件。 打开 Eclipse,选…...
Python学习第十九天
Django-分页 后端分页 Django提供了Paginator类来实现后端分页。Paginator类可以将一个查询集(QuerySet)分成多个页面,每个页面包含指定数量的对象。 from django.shortcuts import render, redirect, get_object_or_404 from .models impo…...
Adobe Premiere Pro2023配置要求
Windows 系统 最低配置 处理器:Intel 第六代或更新版本的 CPU,或 AMD Ryzen™ 1000 系列或更新版本的 CPU,需要支持 Advanced Vector Extensions 2(AVX2)。操作系统:Windows 10(64 位ÿ…...
面试求助:接口测试用例设计主要考虑哪些方面?
一、基础功能验证 1. 正常场景覆盖 关键点:验证接口在合法输入下的正确响应(状态码、数据结构、业务逻辑)。 案例: json 复制 // 用户登录接口 输入:{"username": "合法用户", "password…...
C语言——变量与常量
C语言中的变量与常量:简洁易懂的指南 在C语言编程中,变量和常量是最基本的概念之一。理解它们的区别和使用方法对于编写高效、可维护的代码至关重要。本文将详细介绍C语言中的变量和常量,并通过图表和代码示例帮助你更好地理解。 目录 什么…...
考研408-数据结构完整代码 线性表的顺序存储结构 - 顺序表
线性表的顺序存储结构 - 顺序表 1. 顺序表的定义 用一组地址连续的存储单元依次存储线性表的数据元素,从而使逻辑上相邻的两个元素在物理位置上也相邻 2. 顺序表的特点 随机访问: 即通过首地址和元素序号可以在O(1) 时间内找到指定元素࿰…...
Windows环境下安装部署dzzoffice+onlyoffice的私有网盘和在线协同系统
安装前需要准备好Docker Desktop环境,可查看我的另一份亲测安装文章 https://blog.csdn.net/qq_43003203/article/details/146283915?spm1001.2014.3001.5501 1、安装配置onlyoffice 1、Docker 拉取onlyoffice容器镜像 管理员身份运行Windows PowerShell&#x…...
解决 Docker 镜像拉取超时问题:配置国内镜像源
在使用 Docker 的过程中,经常会遇到镜像拉取超时的问题,尤其是在国内网络环境下。这不仅会浪费大量的时间,还可能导致一些项目无法顺利进行。今天,我将分享一个简单而有效的解决方法:配置国内镜像源。 环境 操作系统 c…...
如何解决 Three.js 物体渲染的锯齿问题
在 Three.js 中,如果模型看起来不够平滑,或者在旋转视角时出现锯齿(aliasing),可以通过以下方法来优化渲染效果。 1. 启用抗锯齿(MSAA) 默认情况下,Three.js 渲染器不会开启抗锯齿&…...
嵌入式八股,为什么单片机中不使用malloc函数
1. 资源限制 单片机的内存资源通常非常有限,尤其是RAM的大小可能只有几KB到几十KB。在这种情况下,使用 malloc 进行动态内存分配可能会导致内存碎片化,使得程序在运行过程中逐渐耗尽可用内存。 2. 内存碎片问题 malloc 函数在分配和释放内…...
【计量地理学】实验一 地理数据的基本统计分析
阅前提示: 计量地理学实验课的实验报告为当堂提交,相较以往实验报告缺少打磨与整理的时间,因此内容中不可避免出现相关错误!!! 出于个人完美主义的原则本不愿发布(其实就是黑历史)…...
ChatPromptTemplate的使用
ChatPromptTemplate 是 LangChain 中专门用于管理多角色对话结构的提示词模板工具。它的核心价值在于,开发者可以预先定义不同类型的对话角色消息(如系统指令、用户提问、AI历史回复),并通过数据绑定动态生成完整对话上下文。 1.…...
SQL Server查询优化
最常用,最有效的数据库优化方式 查询语句层面 避免全表扫描 使用索引:确保查询条件中的字段有索引。例如,查询语句 SELECT * FROM users WHERE age > 20,若 age 字段有索引,数据库会利用索引快速定位符合条件的记…...
Blender插件NodeWrangler导入贴图报错解决方法
Blender用NodeWrangler插件 CtrlShiftT 导入贴图 直接报错 解决方法: 用CtrlshiftT打开需要导入的材质文件夹时,右边有一个默认勾选的相对路径,取消勾选就可以了。 开启node wrangler插件,然后在导入贴图是取消勾选"相对路径"&am…...
QT中的宏
Q_UNUSED(event); 是 Qt 提供的一个宏,用于标记某个变量或参数在当前作用域中未被使用。它的主要作用是避免编译器发出“未使用变量”的警告。 背景 在 C 中,如果一个函数参数或变量在代码中没有被使用,编译器会发出警告,例如&a…...
java项目之基于ssm的药店药品信息管理系统(源码+文档)
项目简介 药店药品信息管理系统实现了以下功能: 个人信息管理 负责管理个人用户的信息。 员工管理 负责管理药店或药品管理机构的员工信息。 药品管理 负责管理药品的详细信息,可能包括药品名称、成分、剂量、价格、库存等。 进货管理 负责管理药品…...
论文分享 | HE-Nav: 一种适用于复杂环境中空地机器人的高性能高效导航系统
阿木实验室始终致力于通过开源项目和智能无人机产品,为全球无人机开发者提供强有力的技术支持,并推出了开源项目校园赞助活动,助力高校学子在学术研究与技术创新中取得更大突破。近日,香港大学王俊铭同学,基于阿木实验…...
【大语言模型】【个人知识库正式内容】提示工程:如何设计模型的提示语
知识库条目:提示工程,如何构建提示词。 🏖️ 当人人都能使用AI时,你如何才能变得更出彩?……让 AI 带有自己的Tag —— 一、简介 什么是提示语 (Prompt): 提示语是用户输入给AI系统的指令或信息, 简单来说…...
ubuntu 24 安装 python3.x 教程
目录 注意事项 一、安装不同 Python 版本 1. 安装依赖 2. 下载 Python 源码 3. 解压并编译安装 二、管理多个 Python 版本 1. 查看已安装的 Python 版本 2. 配置环境变量 3. 使用 update-alternatives 管理 Python 版本 三、使用虚拟环境为项目指定特定 Python 版本…...
(十一) 人工智能 - Python 教程 - Python元组
更多系列教程,每天更新 更多教程关注:xxxueba.com 星星学霸 1 元组(Tuple) 元组是有序且不可更改的集合。在 Python 中,元组是用圆括号编写的。 实例 创建元组: thistuple ("apple", "b…...
【sql靶场】第13、14、17关-post提交报错注入保姆级教程
目录 【sql靶场】第13、14、17关-post提交报错注入保姆级教程 1.知识回顾 1.报错注入深解 2.报错注入格式 3.使用的函数 4.URL 5.核心组成部分 6.数据编码规范 7.请求方法 2.第十三关 1.测试闭合 2.列数测试 3.测试回显 4.爆出数据库名 5.爆出表名 6.爆出字段 …...
93.HarmonyOS NEXT窗口管理基础教程:深入理解WindowSizeManager
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! HarmonyOS NEXT窗口管理基础教程:深入理解WindowSizeManager 文章目录 HarmonyOS NEXT窗口管理基础教程:深入理解WindowSiz…...
Python----数据分析(Pandas一:pandas库介绍,pandas操作文件读取和保存)
一、Pandas库 1.1、概念 Pandas是一个开源的、用于数据处理和分析的Python库,特别适合处理表格类数 据。它建立在NumPy数组之上,提供了高效的数据结构和数据分析工具,使得数据操作变得更加简单、便捷和高效。 Pandas 的目标是成为 Python 数据…...
基于WebRTC技术的EasyRTC嵌入式音视频SDK:多平台兼容与性能优化
在当今数字化、智能化的时代背景下,实时音视频通信技术已成为众多领域不可或缺的关键技术。基于WebRTC技术的EasyRTC嵌入式音视频SDK,凭借其在ARM、Linux、Windows、安卓、iOS等多平台上的兼容性,为开发者提供了强大的工具,推动了…...
【快速入门】MyBatis
一.基础操作 1.准备工作 1)引入依赖 一个是mysql驱动包,一个是mybatis的依赖包: <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><vers…...
提升 React 应用性能:使用 React Profiler 进行性能调优
前言 在现代前端开发中,性能优化是一个不可忽视的重要环节。在 React 生态系统中,React Profiler 是一个强大的工具,它可以帮助我们检测和优化应用的性能。 本文将通过通俗易懂的语言介绍 React Profiler 的作用,并展示如何使用它…...
