Hallo Daniel,
das Problem war (nicht zum erstenmal) die erste Zeile mit dem Status ("100;...") - die ;-Abrennung eines menschenlesbaren Kommentars war noch nicht sinnvoll drin. Außerdem hatte ich keine zeilenweise Behandlung der Socket-Rückgaben eingebaut.
Ist jetzt drin, Tests und Ergebnisse gerne gesehen, müsste mit Deiner Klasse tun nun :).
Viele Grüße
Martin
Code der Klasse:
Instanziierung:Code:<?php /** * @brief minimalistic monitord PHP client - connects via socket and can react on ZVEI, FMS, POCSAG telegrams * @author mdiedrich/Martin Diedrich 08/2013 */ class monitord_php_client { /** * @brief constructor including main() loop */ function monitord_php_client($host='localhost', $port='9333') { $this->host = $host; $this->port = $port; $this->socket = null; $this->sock_retrycount = 0; $this->sock_errcount = 0; $this->errorcode = 0; $this->sleeptime = 10; while($this->monitord_socket_error_handler() === true) { } } /* * @brief split and work through single lines if socket_read contained more then one line * @param $in data read from socket */ function monitord_socket_parse($in) { $monitord_lines_array = explode(PHP_EOL, $in); foreach($monitord_lines_array as $out) { $this->monitord_socket_parse_line($out); } } /** * @brief parses input data from socket, mainly calling function depending on type * @param $in single line to be handled */ function monitord_socket_parse_line($in) { if($in != "") { // cut off human readable information (delimited by ';') first // make it usable in array field named 'human_readable' later $position = strpos($in, ';'); $human_readable = ''; if($position !== false) { $human_readable = substr($in, $position+1); $in = substr($in, 0, $position); } // NEXT LINE FOR DEBUGGING ONLY // echo "\nIN AND HR: " . $in . ' - ' . $human_readable . "\n\n"; // explode machine readable data on ':' and add human readable $monitord_line = explode(':', $in); $monitord_line['human_readable'] = $human_readable; // switch by monitord protocol code switch($monitord_line['0']) { case '300' : $this->monitord_work_zvei($monitord_line);break; case '310' : $this->monitord_work_fms($monitord_line);break; case '320' : $this->monitord_work_pocsag($monitord_line);break; default : $this->monitord_work_unknown($monitord_line); } return true; } else { return false; } } /** * @brief main part, connecting and reading from socket calling parser method * @return bool true normally, false on critical failure */ function monitord_socket_error_handler() { if($this->socket === null) { $socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket === false) { $this->errorcode = socket_last_error($socket); echo 'ERR_ABORT: ' . $this->errorcode; return false; } else { echo "INFO: Socket created.\n"; $this->socket = $socket; } } $out = @socket_read($this->socket, 1024, PHP_BINARY_READ); $this->errorcode = socket_last_error($this->socket); // echo "DEBUG: errorcode was $this->errorcode -- out was "; // var_dump($out); if( ($this->sock_retrycount < 10) && ($this->errorcode == 10054 || $this->errorcode == 10057) ) { if($this->errorcode == 10054) { socket_shutdown($this->socket); socket_close($this->socket); $this->socket = null; return true; } socket_clear_error($this->socket); $address = gethostbyname($this->host); echo "INFO: Trying to connect $address ...\n"; $result = @socket_connect($this->socket, $address, $this->port); if ($result == false) { echo 'WARN: Socket could not be connected. Retrying in ' . ($this->sleeptime * ($this->sock_retrycount+1)) . 's ('; echo $this->sock_retrycount+1 . "/10).\n"; $this->sock_retrycount++; sleep($this->sleeptime * ($this->sock_retrycount+1)); return true; } else { echo "INFO: Socket connected.\n"; $this->sock_retrycount = 0; return true; } } if($this->sock_retrycount == 30) { echo "ERR_ABORT: Socket retrycount (30) exceeded, exiting."; return false; } $this->monitord_socket_parse($out); return true; } /** * @brief handling FMS data * @param $monitord_line (310:{Zeit}:Kanalnummer:FMSKennung:Status:Baustufe:Richtung:TKI:FMSText) */ function monitord_work_fms($monitord_line) { echo "INFO: FMS received [".$monitord_line["2"].":".$monitord_line["3"].":".$monitord_line["6"].":".$monitord_line["4"]."]\n"; } /** * @brief handling ZVEI data * @param $monitord_line (300:Zeit:Kanalnummer(char):Schleife(text5):Sirenenalarmierung(char):Text) */ function monitord_work_zvei($monitord_line) { echo "INFO: ZVEI received [".$monitord_line["2"].":".$monitord_line["3"]."]\n"; } /** * @brief handling POCSAG data */ function monitord_work_pocsag($monitord_line) { echo "INFO: POCSAG received\n"; } /** * @brief handling data of unknown type */ function monitord_work_unknown($monitord_line) { echo "INFO: UNKNOWN received, dumping:\n"; var_dump($monitord_line); echo "\n"; } } ?>
Angepasster Code (abgeleitete Klasse von Daniel):Code:<?php require_once('./monitord_php_client.class.php'); echo "\nmonitord PHP Client v0.2 started\n\n"; $mpc = new monitord_php_client(); ?>
Code:class test_monitord_php_client extends monitord_php_client{ function __construct($host='localhost', $port='9333') { $this->debug = true; parent::__construct($host, $port); } function monitord_work_unknown($monitord_line) { /* * dump all content for debugging process */ echo "INFO: UNKNOWN received, dumping:\n"; var_dump($monitord_line); echo "\n"; /** * Prüfung ob OK empfangen wurde */ if($monitord_line['0'] == '100') { sleep(2); $cmd = "210\r\n"; $write = socket_write($this->socket, $cmd, strlen($cmd)); echo "Es wurden " . $write . " Bytes geschrieben"; echo "\n"; $errorcode = socket_last_error($this->socket); if($errorcode != 0 && $this->debug){ echo "DEBUG: errorcode was $this->errorcode ( " . socket_strerror($errorcode) . " )-- out was "; var_dump($out); } } } }




Zitieren