2012-03-19 7 views

답변

0

: 그것은의 mosquitto 브로커를 시작하는 사람이 경우 출력을 읽고 연결하거나 연결을 끊으면 연결된 클라이언트가있는 xml 문자열을 브로커로 보냅니다. 클라이언트가 주제 "상태/클라이언트 ID가"와 함께 메시지를 게시 할 수 있습니다이를 구현하기

<?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); 
?> 
+1

광산과 매우 유사합니다. 나는 "상태/클라이언트 ID"주제를 관리하기 위해 다른 클라이언트를 사용했습니다. – horacex

2

번호

그것은 더 나은 mosquitto 메일 링리스트에이 논의 될 수

: https://launchpad.net/~mqtt-users 그럼 난 이제 PHP 스크립트를 사용하여 해결 방법을 만들어

4

한 가지 방법 (게시 된 코드는 약간 내가 adiddionally 사용자에 대한 자세한 내용은 데이터베이스를 쿼리로 단순화입니다) 브로커를 연결할 때마다 페이로드 "1", 연결이 끊어지면 페이로드가 "0"입니다.

그런 다음 서버 (브로커) 쪽에서 다른 클라이언트가 "status/#"항목을 구독하면 클라이언트 ID와 페이로드 (연결 여부)를 데이터베이스에 저장합니다.

데이터베이스를 읽으면 어떤 클라이언트가 온라인인지 오프라인인지 정확하게 알 수 있습니다.

+0

당신이 알기를 원한다면 나는 1 년 전에 이것을 알아 냈습니다;) –

+0

잘 알고 있습니다. 당신은 더 나은 /보다 효율적인 방법을 찾을 수 있습니까? :) 단지 클라이언트가 연결 해제시 메시지를 게시 할 것을 기대하는 대신 LWT를 사용하는 것이 더 나은 – horacex

+1

을 배우고 싶습니다. –

2

클라이언트가 (가능한 경우) LWT (Last Will and Testament)를 정의하도록하는 것이 좋습니다. 서버는 LWT가 게시 될 특별한 주제에 가입하고 해당 주제에 게시하지 않는 한 모든 클라이언트를 온라인으로 간주합니다. 배시, NETSTAT GREP을 명령하고 필요 AWK 경우를 통해

MQTT what is the purpose or usage of Last Will Testament?

1

당신은 아마도이 정보를 얻을 수 있습니다. Mosquitto가 1883 번 포트를 사용하고 있다면 다음과 같이 내가 원하는 것을 알려줍니다 :

sudo netstat | grep : 1883