MQTT - Paho IMqttMessageLIstener在监听器线程被阻塞进行操作时错过了消息

时间:2018-03-25 02:29:28

标签: java mqtt paho

我有一个简单的MQTT监听器,可以订阅主题并回调

MqttClient client = new MqttClient(mqttHost, MqttClient.generateClientId());
            client.connect();    
            client.subscribe("test", QUALITY_OF_SERVICE_2, new IMqttMessageListener() {
                public void messageArrived(final String s, final MqttMessage mqttMessage) {

System.out.println("Received"+mqttMessage.toString());
// Code that blocks the thread 
lock.lock();
//do something
lock.unlock();

});

假设我说我正在向主题测试发布1000条消息,但是在tomcat上运行上面的监听器会显示< 1000个控制台输出显示接收器线程未获取所有已发送的消息。

如果没有lock()代码,侦听器将按预期工作并接收所有消息。

1 个答案:

答案 0 :(得分:1)

您不应该在java.util.concurrent处理程序中执行长时间运行/阻塞任务,因为这是在客户端的主网络循环上调用的。

如果您有长时间运行/阻止任务来处理消息,您应该创建一个本地队列,并使用单个本地线程(如果消息顺序很重要)处理来自该队列的消息,或者如果您想要使用线程池尽可能快地处理收到的消息。

Java有一组内置的核心类,用于构建队列和启动线程以使用来自这些队列的消息。查看 $this->db->trans_begin(); if ($this->form_validation->run() == TRUE){ $menu = array( 'menu_name' => $label, 'url' => $path, 'parent_id' => $parent, 'icon' => $icon, 'status' => 1, 'sequence' => $sequence, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), ); $this->db->insert('tbl_menu', $menu); $last_menu_id = $this->db->insert_id(); foreach ($roles as $key => $value) { $permission = array( 'role_id' => $value, 'menu_id' => $last_menu_id, 'status' => 1, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s') ); $this->db->insert('tbl_permissions', $permission); } $this->db->trans_complete(); $trans_status = $this->db->trans_status(); if($trans_status == FALSE){ $this->session->set_flashdata('error','Some issue with data inserting..!!!'); $this->db->trans_rollback(); }else{ $this->session->set_flashdata('success','Menu Added Successfully...!!!'); $this->db->trans_commit(); } }else{ $this->session->set_flashdata('error','You have to fill fields...!!!'); $this->db->trans_rollback(); } 包中的类。