2.1.3.2 注册数据类型并创建主题


    首先, 我们创建一个 MessageTypeSupportImpl 对象, 然后注册带类型名字的类型使用 register_type () 操作的名称。在本例中, 我们将类型注册为空字符串类型名称, 这将导致 MessageTypeSupport 接口存储库标识符用作类型名称。特定类型名称 (如 "Message") 也可用。


Messenger::MessageTypeSupport_var mts =
 new Messenger::MessageTypeSupportImpl();
 if (DDS::RETCODE_OK != mts->register_type(participant, "")) {
 std::cerr << "register_type failed." << std::endl;
 return 1;
 }


    接下来, 我们从类型支持对象获取注册类型名称, 并创建主题通过将类型名称传递给 create_topic () 操作中的参与者。


CORBA::String_var type_name = mts->get_type_name ();
 DDS::Topic_var topic =
 participant->create_topic ("Movie Discussion List",
 type_name,
 TOPIC_QOS_DEFAULT,
 0, // No listener required
 OpenDDS::DCPS::DEFAULT_STATUS_MASK);
 if (!topic) {
 std::cerr << "create_topic failed." << std::endl;
 return 1;
 }


我们已经创建了一个名为 "Movie Discussion List" 的主题, 其注册类型和默认 qos 策略。




2.1.3.3 创建发布者


现在, 我们准备用默认的发布者 qos 创建发布者



DDS::Publisher_var pub =
 participant->create_publisher(PUBLISHER_QOS_DEFAULT,
 0, // No listener required
 OpenDDS::DCPS::DEFAULT_STATUS_MASK);
 if (!pub) {
 std::cerr << "create_publisher failed." << std::endl; 
return 1;
 }


2.1.3.4 创建数据写者并等待订阅者

// Create the datawriter
 DDS::DataWriter_var writer =
 pub->create_datawriter(topic,
 DATAWRITER_QOS_DEFAULT,
 0, // No listener required
 OpenDDS::DCPS::DEFAULT_STATUS_MASK);
 if (!writer) {
 std::cerr << "create_datawriter failed." << std::endl;
 return 1;
 }


当我们创建数据编写器时, 我们传递主题对象引用、默认 qos 策略和空侦听器引用。现在, 我们将数据编写器的引用紧缩到MessageDataWriter 对象引用, 以便我们可以使用类型特定的发布操作。


Messenger::MessageDataWriter_var message_writer =
 Messenger::MessageDataWriter::_narrow(writer);


     示例代码使用conditions和wait sets, 以便发布服务器等待订阅服务器成为连接并完全初始化。在这样一个简单的例子中,
等待订阅服务器可能导致发布服务器在订阅服务器已连接之前发布其示例。


等待订阅服务器所涉及的基本步骤包括:
1) 从我们创建的数据编写器中获取状态条件
2) 在条件中启用发布匹配状态
3) 创建一个等待集
4) 将状态条件附加到等待集
5) 获取发布匹配状态
6) 如果匹配项的当前计数是一个或多个, 则从等待集分离条件
并着手出版
7) 等待设置 (可在指定的时间段内)
8) 循环回到步骤5
下面是相应的代码:

// Block until Subscriber is available
 DDS::StatusCondition_var condition =
 writer->get_statuscondition();
 condition>set_enabled_statuses(
 DDS::PUBLICATION_MATCHED_STATUS);
 DDS::WaitSet_var ws = new DDS::WaitSet;
 ws->attach_condition(condition);
 while (true) {
 DDS::PublicationMatchedStatus matches;
 if (writer->get_publication_matched_status(matches)
 != DDS::RETCODE_OK) {
 std::cerr << "get_publication_matched_status failed!"
 << std::endl;
 return 1;
 }
 if (matches.current_count >= 1) {
 break;
 }
 DDS::ConditionSeq conditions;
 DDS::Duration_t timeout = { 60, 0 };
 if (ws->wait(conditions, timeout) != DDS::RETCODE_OK) {
 std::cerr << "wait failed!" << std::endl;
 return 1;
 }
 }
 ws->detach_condition(condition);




有关状态、条件和等待集的详细信息, 请参阅4章


2.1.3.5 简单发布者


Message发布非常简单:


// Write samples
 Messenger::Message message;
 message.subject_id = 99;
 message.from = "Comic Book Guy";
 message.subject = "Review";
 message.text = "Worst. Movie. Ever.";
 message.count = 0;
 for (int i = 0; i < 10; ++i) {
 DDS::ReturnCode_t error = message_writer->write(message,
 DDS::HANDLE_NIL);
 ++message.count;
 ++message.subject_id;
 if (error != DDS::RETCODE_OK) {
 // Log or otherwise handle the error condition
 return 1;
 }
 }



    对于每个循环迭代, 调用 write () 会使一个消息message被分发到所有连接为我们的主题注册的订阅者。因为 subject_id 是Message的键,每次 subject_id 递增和Write ()被调用 时, 都会创建一个新实例 (请参见1.1.1.3). 要写入的第二个参数 () 指定要在其中发布示例的实例。它应该通过 register_instance 返回的句柄 () 或dds: HANDLE_NIL。传递 dds:: HANDLE_NIL 值指示数据编写器应通过检查示例的键来确定实例。有关详细信息, 请参阅2.2.1 节在发布过程中使用实例句柄