2017-11-22 17 views
1

私はZeroMQの初心者です。ZeroMQのSUB加入者は、ROSのように "コールバック"メカニズムを持っていますか?

私はよくROSを使用します。したがって私はZeroMQの加入者に混乱しています。ほとんどの場合、ROSでは、加入者はコールバック関数を持っています。コールバック関数は、データが対応する装飾体で利用可能なときはいつでも自動的に呼び出されます。

ROS wikiから借りコードスニペット、下記をご覧ください:

void chatterCallback(const std_msgs::String::ConstPtr& msg) 
{ 
    ROS_INFO("I heard: [%s]", msg->data.c_str()); 
} 
//define subscriber and callback function associated with it 
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback); 

しかし、ZeroMQで、以下に示すように、加入者は、データを受信するループ内に保持されているようです:

for (int update_nbr = 0; update_nbr < 100; update_nbr++) 
{ 
    zmq::message_t update; 
    int zipcode, temperature, relhumidity; 
    // receive the data 
    subscriber.recv(&update); 
    // do something with data 
    std::istringstream iss(static_cast<char*>(update.data())); 
    iss >> zipcode >> temperature >> relhumidity; 
} 

上記コードはZeroMQ wikiから借りています。

ROS加入者に似たコールバックメカニズムがZeroMQにも存在しますか?

答えて

1

いいえ、ZMQにコールバックシステムはありません。あなたはメッセージを受け取るためにrecv()を呼び出す必要があります。

recv()を実装することができます.ifの状態とwhileのループでステータスをブロックして返します。私が見

zmq::context_t zmq_context(1); 
zmq::socket_t zmq_socket(zmq_context, ZMQ_SUB); 

zmq_socket.connect("tcp://127.0.0.1:58951"); 

std::string TOPIC = ""; 

zmq_socket.setsockopt(ZMQ_SUBSCRIBE, TOPIC.c_str(), TOPIC.length()); // allow all messages 
zmq_socket.setsockopt(ZMQ_RCVTIMEO, 1000); // Timeout to get out of the while loop since recv is blocking 
while(run) { 
    zmq::message_t msg; 
    int rc = zmq_socket.recv(&msg); // Is blocking until you receive a message 
    if(rc) { 
     // You received a message : your data is in msg 
     // Do stuff here : call your function with the parameters received from zmq 
    } 
} 
// Clean up your socket and context here 
zmq_socket.setsockopt(ZMQ_LINGER, linger); 
zmq_socket.close(); 
zmq_context.close(); 
+0

私は頻繁にタイムアウトとこのようなパターンを使用します。 'zmq_socket.recv(&msg)'が同じメッセージを再び受信する可能性はありますか? 'while'ループが速すぎるか、それとも何かの可能性がありますか?それが意味をなさないかどうかわからない。 –

+0

マルチパートメッセージを送信していないと仮定すると、1つのメッセージが送信された場合、1つのメッセージだけが受信されます。ループが速すぎることはありません。なぜなら、メッセージが受信されるか、タイムアウトに達するまで、 'recv'呼び出しをブロックするからです。 – Clonk

+0

うん。もう1つの質問。 *購読者*がそれに接続されているかどうかを知ることができる方法はありますか?基本的には、私は*出版社*の仕事を中断して、* subscriber *が接続されたときにのみ再開できることを考えています。 –

関連する問題