Ergebnis 1 bis 6 von 6

Thema: PHP-Socketclient für den monitord

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #4
    Registriert seit
    15.11.2007
    Beiträge
    213
    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:
    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";
    	}
    	
    }
    
    ?>
    Instanziierung:
    Code:
    <?php
    
    	require_once('./monitord_php_client.class.php');
    	
    	echo "\nmonitord PHP Client v0.2 started\n\n";
    	
    	$mpc = new monitord_php_client();
    	
    ?>
    Angepasster Code (abgeleitete Klasse von Daniel):
    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);
    			}
    		}
    	}
    	
    }
    Geändert von mdi (06.08.2013 um 14:47 Uhr)

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •