从MQTT客户端获取已连接客户端ID的列表
以及我现在创建使用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);
?>
一个方法是让客户端发布消息,主题为“状态/客户端ID”和每次连接代理时有效载荷“1”,断开连接时有效载荷“0”。
然后在服务器(代理)端,设置另一个客户端订阅主题“status /#”,当它收到任何类似的消息时,将client-id和payload(连接与否)存储到数据库中。
然后你可以读取数据库,以确切地知道哪个客户端在线或离线。
如果你会读,你会知道我只是在我自己一年之前就明白了这一点;) – 2013-03-12 10:35:44
有用的知识。你找到一个更好/更有效的方法来做到这一点? :)只是想更好地学习 – horacex 2013-03-12 13:00:21
只使用LWT而不是期望客户端在断开连接时发布消息。 – 2015-10-19 20:38:02
一个很好的解决方法是让客户(如果可能的话)定义一个最后的遗嘱(LWT)。您的服务器将订阅LWT将发布到的一个特殊主题,并将所有客户端视为在线,除非他们发布到该主题。
通过BASH命令netstat的,grep和必要时的awk你大概可以得到这个信息。如果Mosquitto使用的是1883端口,那么以下将告诉你我想要的东西:
sudo netstat | grep:1883
与我的非常相似。我用另一个客户端来管理“status/client-id”主题。 – horacex 2013-03-12 13:01:55