<< 点击显示目录 >> 主页 exOS使用助手 > exOS Automation Help > Development > Programming > exOS Communication API reference (exos_api.h) > EXOS_CONNECTION_STATE |
数据模型/数据集 连接状态
typedef enum
{
EXOS_STATE_DISCONNECTED,
EXOS_STATE_CONNECTED,
EXOS_STATE_OPERATIONAL,
EXOS_STATE_ABORTED
} EXOS_CONNECTION_STATE;
•EXOS_STATE_DISCONNECTED: 系统启动时,每个数据模型和数据集都将处于 EXOS_STATE_DISCONNECTED 状态。如果数据模型或数据集已经启动并运行,EXOS_STATE_DISCONNECTED 表示数据模型或数据集已从服务器断开连接。如果使用 exos_datamodel_disconnect()断开了数据模型与服务器 的连接, 或者使用 exos_dataset_disconnect()断开了数据集与服务器的连接,就会发生这种情况 。如果数据模型或数据集是由于其他原因(即不是由用户触发的)从服务器断开连接的,则 connection_state 将进入 EXOS_STATE_ABORTED。
通过 exos_datamodel_disconnect()关闭连接的对面站(即远程系统中的应用程序)也会达到这种状态 。与从当前应用程序触发并 终止 与数据集消息路由器的所有连接的情况不同 ,从对面站断开连接不会中断与本地 数据集消息路由器的 连接 。这样,接收到 EXOS_STATE_DISCONNECTED 事件的本地应用程序可能会停止一些正在运行的进程,但不需要调用任何其他 exOS API 函数来重新获得连接。一旦对端站重新连接到远程 数据集消息路由器,并与本地 数据集消息路由器同步 ,当前应用程序就会收到 EXOS_STATE_CONNECTED 事件。
•EXOS_STATE_CONNECTED: 数据模型已在 数据集消息路由器上成功初始化 ,但尚未启动。数据模型由任何一方用 exos_datamodel_set_operational()启动 ,在进入运行状态前,数据集的参数设置/配置 都是由exos_datamodel_set_operational()完成的。对于数据集来说,这意味着在 数据集消息路由器(Dataset Message Router)上找到了匹配的变量或结构 ,而且在数据模型启动之前,所有连接到数据模型的数据集也都处于 EXOS_STATE_CONNECTED 状态。
•EXOS_STATE_OPERATIONAL: 数据模型已初始化,客户端已完成配置序列,这意味着它已进入运行状态。这是向应用程序发出的一条信息,即所有数据集现在都可以读取了,因此连接到此数据模型的所有数据集上的所有数据集事件回调都将以 EXOS_STATE_OPERATIONAL 状态调用。
•EXOS_STATE_ABORTED: 数据集消息路由器 发生 运行时错误 。请查看错误成员的 EXOS_ERROR_CODE。使用 exos_get_error_string() 获取该错误的文本表示(ASCII 字符串)。
连接状态在处理数据模型和数据集时起着核心作用。例如,由于 Linux 应用程序可以作为 AR 系统的子模块运行,因此在运行任何有意义的代码之前,应用程序必须知道与 AR 系统的连接处于活动状态。
因此,每个数据模型都有一个连接状态和一个相应的事件回调,以通知应用程序连接是否处于启动或关闭状态。
同样,每个数据集都有一个连接状态和一个回调事件,如果该数据集在服务器上发生了状态变化或错误,就会发出信号。
每个 exos_datamodel_handle_t 和 exos_dataset_handle_t都 有一个连接状态(connection_state)成员,可以通过查询该成员来获取当前的连接状态。
状态机是这样工作的:
•系统启动时,每个数据集和数据模型都处于 EXOS_STATE_DISCONNECTED 状态。但这种初始状态不会触发回调。
•函数 exos_datamodel_connect_() 和 exos_dataset_connect() 会尝试让数据模型或数据集进入 EXOS_STATE_CONNECTED 状态。如果失败,数据模型或数据集将进入 EXOS_STATE_ABORTED 状态。在许多情况下,在函数级别上已经检测到了错字或类似错误。为此,所有函数都要使用 EXOS_ASSERT_OK 宏。
•数据模型的状态会对所附数据集产生影响,这意味着如果数据模型进入 EXOS_STATE_ABORTED 或 EXOS_STATE_DISCONNECTED,所有数据集都会进入相同的状态。
•当数据模型从 EXOS_STATE_CONNECTED 进入 EXOS_STATE_OPERATIONAL (由 exos_datamodel_set_operational()触发)时,也会出现类似的模式 。在这种情况下,数据模型上所有处于 EXOS_STATE_CONNECTED 状态的数据集都会进入 EXOS_STATE_OPERATIONAL 状态。处于 EXOS_STATE_DISCONNECTED 或 EXOS_STATE_ABORTED 状态的数据集将保持不变。之所以需要这条命令,是为了让应用程序能在实际启动前对数据集进行参数化(配置)。
•如果出现任何运行时错误,比如应用程序无意中失去了与服务器的连接,数据模型就会连同其附加数据集一起进入 EXOS_STATE_ABORTED。
•数据模型和数据集也可以使用 exos_datamodel_disconnect() 或 exos_dataset_disconnect()回到其初始的 EXOS_STATE_DISCONNECTED 状态 。
每个数据模型和数据集都有一个数据模型事件(datamodelEvent)和数据集事件(datasetEvent)回调,分别通知事件类型为 EXOS_DATAMODEL_EVENT_CONNECTION_CHANGED 和 EXOS_DATASET_EVENT_CONNECTION_CHANGED 的连接状态(connection_state)成员发生变化。
如果数据模型或数据集在服务器上出错,连接状态将进入 EXOS_STATE_ABORTED。在这种情况下,错误编号会在错误成员(EXOS_ERROR_CODE 中的预定义数据集之一)中找到。
数据模型事件示例:
static void datamodelEvent(exos_datamodel_handle_t *datamodel, const EXOS_DATAMODEL_EVENT_TYPE event_type, void *info)
{
switch (event_type)
{
case EXOS_DATASET_EVENT_CONNECTION_CHANGED:
INFO("application changed state to %s", exos_get_state_string(datamodel->connection_state));
switch (datamodel->connection_state)
{
case EXOS_STATE_DISCONNECTED:
break;
case EXOS_STATE_CONNECTED:
break;
case EXOS_STATE_OPERATIONAL:
SUCCESS("Application operational!");
break;
case EXOS_STATE_ABORTED:
ERROR("application error %d (%s) occured", datamodel->error, exos_get_error_string(datamodel->error));
break;
}
break;
}
}
数据集事件示例:
static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
{
switch (event_type)
{
case EXOS_DATASET_EVENT_CONNECTION_CHANGED:
INFO("dataset %s changed state to %s", dataset->name, exos_get_state_string(dataset->connection_state));
switch (dataset->connection_state)
{
case EXOS_STATE_DISCONNECTED:
break;
case EXOS_STATE_CONNECTED:
//call the dataset changed event to update the dataset
//datasetChanged(dataset);
break;
case EXOS_STATE_OPERATIONAL:
break;
case EXOS_STATE_ABORTED:
ERROR("dataset error %d (%s) occured", dataset->error, exos_get_error_string(dataset->error));
break;
}
break;
}
}
在处理数据集时,如果 event_type = EXOS_DATASET_EVENT_UPDATED,检查 connection_state 可能很有用。例如
static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
{
switch (event_type)
{
case EXOS_DATASET_EVENT_UPDATED:
if(dataset->connection_state != EXOS_STATE_OPERATIONAL) return;
...
datamodel / dataset Connection State
typedef enum
{
EXOS_STATE_DISCONNECTED,
EXOS_STATE_CONNECTED,
EXOS_STATE_OPERATIONAL,
EXOS_STATE_ABORTED
} EXOS_CONNECTION_STATE;
•EXOS_STATE_DISCONNECTED: At the start of the system, each datamodel and dataset will be in state EXOS_STATE_DISCONNECTED. In case the datamodel or dataset has been up and running, EXOS_STATE_DISCONNECTED means the datamodel or dataset was disconnected from the server. This happens if the datamodel is disconnected from the server using exos_datamodel_disconnect() or if the dataset was disconnected with exos_dataset_disconnect(). If the datamodel or dataset was disconnected from the server due to some other reason, i.e. not triggered by the user, the connection_state will go into EXOS_STATE_ABORTED.
This state is also reached by the opposite station (i.e. an application on the remote system) closing the connection via exos_datamodel_disconnect(). Unlike the situation where this is triggered from the current application and all connections to the Dataset Message Router are terminated, a disconnect from the opposite station will not interrupt the connection to the local Dataset Message Router. In this way, the local application that receives the event EXOS_STATE_DISCONNECTED may stop some of its running processes, but does not need to call any other exOS API functions to regain the connection. As soon as the opposite station reconnects to the remote Dataset Message Router, and this one synchronizes with the local Dataset Message Router, the current application recieves an EXOS_STATE_CONNECTED event.
•EXOS_STATE_CONNECTED: The datamodel successfully initialized its datamodel on the Dataset Message Router, but has not yet been started. The datamodel is started by either side with an exos_datamodel_set_operational(), which enables the parametrizaton / configuration of datasets before it goes into operational state. For datasets it means that the matching variable or structure has been found on the Dataset Message Router, and until the datamodel has been started, all datasets attached to the datamodel are also in the EXOS_STATE_CONNECTED state.
•EXOS_STATE_OPERATIONAL: The datamodel is initialized and the client has finished its configuration sequence meaning that it has gone into operational state. This is a message to the application that all datasets are now ready for reading, and thus all datasetEvent callbacks on all datasets connected to this datamodel will be called with an EXOS_STATE_OPERATIONAL state.
•EXOS_STATE_ABORTED: A runtime error from the Dataset Message Router has occured. Please see the error member for the EXOS_ERROR_CODE. Use exos_get_error_string() to get the textual representation (ASCII string) for this error.
The connection state plays a central role in handling datamodels and datasets. For example, as the Linux application can run as a submodule of the Automation Runtime system, it is necessary for the application to know that the connection to the Automation Runtime system is active before running any meaningful code.
For this reason, every datamodel has a connection state and a corresponding event callback to notify the application if the connection is basically up or down.
Likewise, every dataset has a connection state and a callback that signals if this dataset has experienced a state change or error on the server.
Each exos_datamodel_handle_t and exos_dataset_handle_t has a connection_state member which can be queried in order to get the current state of the connection.
The state machine works like this:
•At start of the system, each dataset and datamodel is in the EXOS_STATE_DISCONNECTED state. This first intial state will however not trigger the callback.
•the functions exos_datamodel_connect_() and exos_dataset_connect() then try to get the datamodel or dataset into the EXOS_STATE_CONNECTED state. If this fails, the datamodel or dataset will go into the EXOS_STATE_ABORTED state. In many cases a typo or similar is already detected on the function level. For that, surround all functions with the EXOS_ASSERT_OK macro.
•The state of the datamodel has an impact on the attached datasets, meaning that if the datamodel enters EXOS_STATE_ABORTED or EXOS_STATE_DISCONNECTED, all datasets will enter the same state.
•A similar pattern occurs when the datamodel goes from EXOS_STATE_CONNECTED to EXOS_STATE_OPERATIONAL, which is triggered from the exos_datamodel_set_operational(). In this case, all datasets attached to the datamodel that are in EXOS_STATE_CONNECTED will enter the state EXOS_STATE_OPERATIONAL. Datasets that are in the state EXOS_STATE_DISCONNECTED or EXOS_STATE_ABORTED will stay there. The reason for having this command is to enable the application to parametrize datasets (configuration) before it is actually started.
•If any runtime error occurs, like the application is unintentionally loosing the connection to the server, the datamodel will go into EXOS_STATE_ABORTED along with its attached datasets.
•datamodels and datasets can also return to their initial EXOS_STATE_DISCONNECTED state using the exos_datamodel_disconnect() or exos_dataset_disconnect().
Each datamodel and dataset has a datamodelEvent respectively datasetEvent callback which notfies of a change to the connection_state member with the event_type EXOS_DATAMODEL_EVENT_CONNECTION_CHANGED respectively EXOS_DATASET_EVENT_CONNECTION_CHANGED.
In case the datamodel or the dataset encounters an error on the server, the connection_state will go into EXOS_STATE_ABORTED. In this case, the error number is found in the error member, which is one of the predefined datasets in EXOS_ERROR_CODE.
Example for the datamodel event:
static void datamodelEvent(exos_datamodel_handle_t *datamodel, const EXOS_DATAMODEL_EVENT_TYPE event_type, void *info)
{
switch (event_type)
{
case EXOS_DATASET_EVENT_CONNECTION_CHANGED:
INFO("application changed state to %s", exos_get_state_string(datamodel->connection_state));
switch (datamodel->connection_state)
{
case EXOS_STATE_DISCONNECTED:
break;
case EXOS_STATE_CONNECTED:
break;
case EXOS_STATE_OPERATIONAL:
SUCCESS("Application operational!");
break;
case EXOS_STATE_ABORTED:
ERROR("application error %d (%s) occured", datamodel->error, exos_get_error_string(datamodel->error));
break;
}
break;
}
}
Example for the dataset event:
static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
{
switch (event_type)
{
case EXOS_DATASET_EVENT_CONNECTION_CHANGED:
INFO("dataset %s changed state to %s", dataset->name, exos_get_state_string(dataset->connection_state));
switch (dataset->connection_state)
{
case EXOS_STATE_DISCONNECTED:
break;
case EXOS_STATE_CONNECTED:
//call the dataset changed event to update the dataset
//datasetChanged(dataset);
break;
case EXOS_STATE_OPERATIONAL:
break;
case EXOS_STATE_ABORTED:
ERROR("dataset error %d (%s) occured", dataset->error, exos_get_error_string(dataset->error));
break;
}
break;
}
}
When working with datasets, it can be useful to check the connection_state in case of the event_type = EXOS_DATASET_EVENT_UPDATED. For example:
static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
{
switch (event_type)
{
case EXOS_DATASET_EVENT_UPDATED:
if(dataset->connection_state != EXOS_STATE_OPERATIONAL) return;
...