Module: nagvis
Branch: master
Commit: ce41cfbd025a5c46c6b09a1fb33a7fe7b3aca38b
URL:    
http://nagvis.git.sourceforge.net/git/gitweb.cgi?p=nagvis/nagvis;a=commit;h=ce41cfbd025a5c46c6b09a1fb33a7fe7b3aca38b

Author: LaMi <[email protected]>
Date:   Mon Nov 16 09:38:25 2009 +0100

The backend uses a persistent connection for each NagVis call. No need to open 
a new connection to the socket for each livestatus query anymore

---

 .../core/classes/GlobalBackendmklivestatus.php     |  108 +++++++++++++++-----
 1 files changed, 82 insertions(+), 26 deletions(-)

diff --git a/share/server/core/classes/GlobalBackendmklivestatus.php 
b/share/server/core/classes/GlobalBackendmklivestatus.php
index 4d867a7..20c8a21 100644
--- a/share/server/core/classes/GlobalBackendmklivestatus.php
+++ b/share/server/core/classes/GlobalBackendmklivestatus.php
@@ -37,6 +37,7 @@
 class GlobalBackendmklivestatus implements GlobalBackendInterface {
        private $backendId = '';
        
+       private $SOCKET = null;
        private $socketType = '';
        private $socketPath = '';
        private $socketAddress = '';
@@ -131,66 +132,100 @@ class GlobalBackendmklivestatus implements 
GlobalBackendInterface {
                        return false;
                }
        }
-       
+
        /**
-        * PRIVATE queryLivestatus()
+        * PRIVATE connectSocket()
         *
-        * Queries the livestatus socket and returns the result as array
+        * Connects to the livestatus socket when no connection is open
         *
-        * @param   String   Query to send to the socket
-        * @return  Array    Results of the query
-   * @author  Mathias Kettner <[email protected]>
         * @author  Lars Michelsen <[email protected]>
         */
-       private function queryLivestatus($query) {
-               $sock = false;
-               
+       private function connectSocket() {
                // Create socket connection
                if($this->socketType === 'unix') {
-                       $sock = socket_create(AF_UNIX, SOCK_STREAM, 0);
+                       $this->SOCKET = socket_create(AF_UNIX, SOCK_STREAM, 0);
                } elseif($this->socketType === 'tcp') {
-                       $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+                       $this->SOCKET = socket_create(AF_INET, SOCK_STREAM, 
SOL_TCP);
                }
                
-               if($sock == false) {
+               if($this->SOCKET == false) {
                        new GlobalMessage('ERROR', 
GlobalCore::getInstance()->getLang()->getText('Could not create livestatus 
socket [SOCKET] in backend [BACKENDID].', Array('BACKENDID' => 
$this->backendId, 'SOCKET' => $this->socketPath)));
                        return Array();
                }
                
                // Connect to the socket
                if($this->socketType === 'unix') {
-                       $result = socket_connect($sock, $this->socketPath);
+                       $result = socket_connect($this->SOCKET, 
$this->socketPath);
                } elseif($this->socketType === 'tcp') {
-                       $result = socket_connect($sock, $this->socketAddress, 
$this->socketPort);
+                       $result = socket_connect($this->SOCKET, 
$this->socketAddress, $this->socketPort);
                }
                
                if($result == false) {
-                       new GlobalMessage('ERROR', 
GlobalCore::getInstance()->getLang()->getText('Unable to connect to the 
[SOCKET] in backend [BACKENDID]: [MSG]', Array('BACKENDID' => $this->backendId, 
'SOCKET' => $this->socketPath, 'MSG' => 
socket_strerror(socket_last_error($sock)))));
+                       new GlobalMessage('ERROR', 
GlobalCore::getInstance()->getLang()->getText('Unable to connect to the 
[SOCKET] in backend [BACKENDID]: [MSG]', Array('BACKENDID' => $this->backendId, 
'SOCKET' => $this->socketPath, 'MSG' => 
socket_strerror(socket_last_error($this->SOCKET)))));
                        return Array();
                }
+       }
+       
+       /**
+        * PRIVATE queryLivestatus()
+        *
+        * Queries the livestatus socket and returns the result as array
+        *
+        * @param   String   Query to send to the socket
+        * @return  Array    Results of the query
+        * @author  Mathias Kettner <[email protected]>
+        * @author  Lars Michelsen <[email protected]>
+        */
+       private function queryLivestatus($query) {
+               // Only connect when no connection opened yet
+               if($this->SOCKET === null) {
+                       $this->connectSocket();
+               }
                
                // Query to get a json formated array back
-               socket_write($sock, $query . "OutputFormat:json\n");
-               socket_shutdown($sock, 1);
+               // Use KeepAlive with fixed16 header
+               socket_write($this->SOCKET, $query . 
"OutputFormat:json\nKeepAlive: on\nResponseHeader: fixed16\n\n");
+               
+               // Read 16 bytes to get the status code and body size
+               $read = $this->readSocket(16);
+               
+               // Catch problem while reading
+               if($read === false) {
+                       new GlobalMessage('ERROR', 
GlobalCore::getInstance()->getLang()->getText('Problem while reading from 
socket [SOCKET] in backend [BACKENDID]: [MSG]', Array('BACKENDID' => 
$this->backendId, 'SOCKET' => $this->socketPath, 'MSG' => 
socket_strerror(socket_last_error($this->SOCKET)))));
+               }
+               
+               // Extract status code
+               $status = substr($read, 0, 3);
                
-               // Read all information from the response and add it to a string
-               $read = '';
-               while('' != ($r = @socket_read($sock, 65536))) {
-                       $read .= $r;
+               // Extract content length
+               $len = intval(trim(substr($read, 4, 11)));
+               
+               // Read socket until end of data
+               $read = $this->readSocket($len);
+               
+               // Catch problem while reading
+               if($read === false) {
+                       new GlobalMessage('ERROR', 
GlobalCore::getInstance()->getLang()->getText('Problem while reading from 
socket [SOCKET] in backend [BACKENDID]: [MSG]', Array('BACKENDID' => 
$this->backendId, 'SOCKET' => $this->socketPath, 'MSG' => 
socket_strerror(socket_last_error($this->SOCKET)))));
+               }
+               
+               // Catch errors (Like HTTP 200 is OK)
+               if($status != "200") {
+                       new GlobalMessage('ERROR', 
GlobalCore::getInstance()->getLang()->getText('Problem while reading from 
socket [SOCKET] in backend [BACKENDID]: [MSG]', Array('BACKENDID' => 
$this->backendId, 'SOCKET' => $this->socketPath, 'MSG' => $read)));
                }
                
                // Catch problems occured while reading? 104: Connection reset 
by peer
-               if(socket_last_error($sock) == 104) {
-                       new GlobalMessage('ERROR', 
GlobalCore::getInstance()->getLang()->getText('Problem while reading from 
socket [SOCKET] in backend [BACKENDID]: [MSG]', Array('BACKENDID' => 
$this->backendId, 'SOCKET' => $this->socketPath, 'MSG' => 
socket_strerror(socket_last_error($sock)))));
+               if(socket_last_error($this->SOCKET) == 104) {
+                       new GlobalMessage('ERROR', 
GlobalCore::getInstance()->getLang()->getText('Problem while reading from 
socket [SOCKET] in backend [BACKENDID]: [MSG]', Array('BACKENDID' => 
$this->backendId, 'SOCKET' => $this->socketPath, 'MSG' => 
socket_strerror(socket_last_error($this->SOCKET)))));
                        return Array();
                }
                
-               // Important: The socket needs to be closed after reading
-               socket_close($sock);
-               
                // Decode the json response
                $obj = json_decode($read);
                
+               // TEST: Disable KeepAlive:
+               //socket_close($this->SOCKET);
+               //$this->SOCKET = null;
+               
                // json_decode returns null on syntax problems
                if($obj === null) {
                        new GlobalMessage('ERROR', 
GlobalCore::getInstance()->getLang()->getText('The response has an invalid 
format in backend [BACKENDID].', Array('BACKENDID' => $this->backendId)));
@@ -200,6 +235,27 @@ class GlobalBackendmklivestatus implements 
GlobalBackendInterface {
                        return $obj;
                }
        }
+
+       public function readSocket($len) {
+               $offset = 0;
+               $socketData = '';
+               
+               while($offset < $len) {
+                       if(($data = @socket_read($this->SOCKET, $len-$offset)) 
=== false) {
+                               return false;
+                       }
+               
+                       $dataLen = strlen ($data);
+                       $offset += $dataLen;
+                       $socketData .= $data;
+                       
+                       if($dataLen == 0) {
+                               break;
+                       }
+               }
+               
+               return $socketData;
+       }
        
        /**
         * PRIVATE queryLivestatusSingle()


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Nagvis-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/nagvis-checkins

Reply via email to