作为连接到mosquitto的mqtt客户端,是否可以检索也连接到代理的客户端ID列表?
答案 0 :(得分:8)
实现这一点的一种方法是让客户端每次连接代理时都发布主题为“status / client-id”和有效负载“1”的消息,并在断开连接时发布有效负载“0”。
然后在服务器(代理)端,设置另一个客户端订阅主题“status /#”,当它收到这样的消息时,将client-id和payload(已连接或未连接)存储到数据库中。
然后您可以读取数据库以确切知道哪个客户端在线或离线。
答案 1 :(得分:3)
没有
在mosquitto邮件列表上讨论这个问题可能会更好:https://launchpad.net/~mqtt-users
答案 2 :(得分:2)
一个好的解决方法是让客户(如果可能的话)定义最后遗嘱和遗嘱(LWT)。您的服务器将订阅一个特殊主题,其中将发布LWT并将所有客户端视为在线,除非他们发布到该主题。
答案 3 :(得分:1)
您可以通过BASH命令netstat,grep以及必要的awk获取此信息。如果Mosquitto使用端口1883,那么以下内容将告诉您我想要的内容:
sudo netstat | grep:1883
答案 4 :(得分:1)
正如@ user1048839所说,使用客户端的LWT
并在线发布消息,
在自定义主题上维护客户状态。
为该主题添加下标并维护客户列表自身。
如果pub retain
消息,则sub将获得客户端列表。
官方代码不支持online_list,
所以我修补了mosquitto 1.5.4,添加了2个自定义sys主题:
mosquitto_sub -i DDD -v -t '$SYS/broker/chen_list'
$SYS/broker/chen_list
0 - CLOUD0_19108
1 - EEE
2 - DDD
mosquitto_sub -i DDD -v -t '$SYS/broker/chen_state/#'
$SYS/broker/chen_state/DDD 1
$SYS/broker/chen_state/EEE 1
$SYS/broker/chen_state/CLOUD0_19108 1
$SYS/broker/chen_state/EEE 0
$SYS/broker/chen_state/EEE 1
//如果发布retain
消息,则本主题下的子主题可以使所有客户端处于联机状态(在有效负载中)。
github上的源代码:
答案 5 :(得分:0)
我现在使用PHP脚本创建了一个解决方法:它启动mosquitto代理,读取输出,如果有人连接或断开连接,它会将连接的客户端的xml字符串发送给代理。 (发布的代码有点简化,因为我在adiddionally查询数据库以获取有关用户的更多信息)
<?php
require('SAM/php_sam.php');
if (!$handle = popen('mosquitto 2>&1', 'r')) {
die('could not start mosquitto');
}
function usersToXML($users) {
$xml = '<?xml version="1.0"?><userlist>';
foreach($users as $user) {
$xml .= '<user>' .
'<id><![CDATA['. $user->id .']]></id>' .
'</user>';
}
$xml .= '</userlist>';
return $xml;
}
function updateBroadcast($users) {
sleep(1);
ob_start();
$conn = new SAMConnection();
$conn->Connect(SAM_MQTT, array(
SAM_HOST => '127.0.0.1',
SAM_PORT => 1883
));
$conn->Send('topic://broadcast', (object)array('body' => usersToXML($users)));
$conn->Disconnect();
ob_end_clean();
}
while($line = fread($handle, 2096)) {
echo $line;
if (preg_match('/New client connected from .+ as user_(\d+)./', $line, $regs)) {
$user = (object)array('id' => $regs[1]);
$connectedUsers[$user->id] = $user;
updateBroadcast($connectedUsers);
} else if (preg_match('/Received DISCONNECT from user_(\d+)/', $line, $regs) ||
preg_match('/Client user_(\d+) has exceeded timeout, disconnecting./', $line, $regs) ||
preg_match('/Socket read error on client user_(\d+), disconnecting./', $line, $regs)) {
if (isset($connectedUsers[$regs[1]])) {
unset($connectedUsers[$regs[1]]);
updateBroadcast($connectedUsers);
}
}
}
pclose($handle);
?>