2017-11-22 42 views
1

저는 ZeroMQ에서 초보자입니다.ZeroMQ의 SUB 가입자는 ROS처럼 "콜백"메커니즘을 가지고 있습니까?

자주 ROS을 사용합니다. 따라서 저는 ZeroMQ 가입자에게 혼란스러워합니다. ROS에서 대부분의 시간 동안 가입자는 데이터를 사용할 수있을 때마다 자동으로 호출되는 콜백 함수를 가지고 있습니다. 그것은 다음과 같이 그 가입자가 데이터를 수신하는 루프에 보관되어 보인다

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에 :

ROS wiki에서 차용, 코드는 아래를 참조하시기 바랍니다

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

다중 메시지를 보내지 않는다고 가정 할 때 하나의 메시지가 전송되면 하나의 메시지 만 수신됩니다. 루프가 너무 빠르지는 않습니다. 왜냐하면 메시지가 수신되거나 타임 아웃에 도달 할 때까지'recv' 호출을 차단할 것이기 때문입니다. – Clonk

+0

예. 한 가지 더 묻습니다. * 구독자 *가 연결되어 있는지 여부를 게시자가 알 수있는 방법이 있습니까? 기본적으로 내가 생각하는 것은 * 게시자 *의 작업을 일시 중지하고 * subscriber *가 연결된 경우에만 다시 시작할 수 있다는 것입니다. –