如何使用RTI DDS确定已删除DataWriter的type_name

How to determine that type_name of a deleted DataWriter using RTI DDS

本文关键字:DataWriter type name 删除 RTI 何使用 DDS      更新时间:2023-10-16

我正在使用RTI DDS 5.2用c++编写一个工具,需要检测何时删除datawriter并知道相关数据的type_name。我使用的代码类似于这个和这个。

我使用的是DDSWaitSet,当DataWriter被delete_datawriter删除时,它会被触发,但SampleInfo表明数据无效,并且足够肯定,数据样本type_name为空。

是否有一种方法可以删除DataWriter,从而使内置主题订阅获得type_name ?或者我可以设置QOS设置来修复此行为?

找到了解决此问题的方法。我仍然不知道如何使它,所以数据样本是有效的,当DataWriter消失,但SampleInfo确实有字段instance_state唯一标识的作家。解决方案是在数据有效时跟踪type_names,并在数据无效时查找它。下面是我用来解决这个问题的代码要点:

struct cmp_instance_handle {
    bool operator()(const DDS_InstanceHandle_t& a, const DDS_InstanceHandle_t& b) const {
        return !DDS_InstanceHandle_equals(&a, &b);
    }
};
void wait_for_data_writer_samples()
{
    ConditionSeq cs;
    DDSWaitSet* ws = new DDSWaitSet();
    StatusCondition* condition = _publication_dr->get_statuscondition();
    DDS_Duration_t timeout = {DDS_DURATION_INFINITE_SEC, DDS_DURATION_INFINITE_NSEC};
    std::map<DDS_InstanceHandle_t, std::string, cmp_instance_handle> instance_handle_map;
    ws->attach_condition(condition);
    condition->set_enabled_statuses(DDS_STATUS_MASK_ALL);
    while(true) {
        ws->wait(cs, timeout);
        PublicationBuiltinTopicDataSeq data_seq;
        SampleInfoSeq info_seq;
        _publication_dr->take(
            data_seq,
            info_seq,
            DDS_LENGTH_UNLIMITED,
            ANY_SAMPLE_STATE,
            ANY_VIEW_STATE,
            ANY_INSTANCE_STATE
        );
        int len = data_seq.length();
        for(int i = 0; i < len; ++i) {
            DDS_InstanceHandle_t instance_handle = info_seq[i].instance_handle;
            if(info_seq[i].valid_data) {
                std::string type_name(data_seq[i].type_name);
                // store the type_name in the map for future use
                instance_handle_map[instance_handle] = type_name;
                if(info_seq[i].instance_state == DDS_InstanceStateKind::DDS_ALIVE_INSTANCE_STATE) {
                    do_data_writer_alive_callback(type_name);
                }
                else {
                    // If the data is valid, but not DDS_ALIVE_INSTANCE_STATE, the DataWriter died *and* we can 
                    // directly access the type_name so we can handle that case here
                    do_data_writer_dead_callback(type_name);
                }
            }
            else {
                // If the data is not valid then the DataWriter is definitely not alive but we can't directly access
                // the type_name. Fortunately we can look it up in our map.
                do_data_writer_dead_callback(instance_handle_map[instance_handle]);
                // at this point the DataWriter is gone so we remove it from the map.
                instance_handle_map.erase(instance_handle);
            }
        }
        _publication_dr->return_loan(data_seq, info_seq);
    }
}