Author: ihabunek
Date: Thu Dec  8 15:10:45 2011
New Revision: 1211929

URL: http://svn.apache.org/viewvc?rev=1211929&view=rev
Log:
LOG4PHP-154: Rewritten LoggerAppenderSocket to use a layout.

Added:
    logging/log4php/trunk/src/test/php/appenders/socketServer.php
Modified:
    logging/log4php/trunk/src/changes/changes.xml
    logging/log4php/trunk/src/main/php/appenders/LoggerAppenderSocket.php
    logging/log4php/trunk/src/site/xdoc/docs/appenders/socket.xml
    logging/log4php/trunk/src/test/php/appenders/LoggerAppenderSocketTest.php

Modified: logging/log4php/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/logging/log4php/trunk/src/changes/changes.xml?rev=1211929&r1=1211928&r2=1211929&view=diff
==============================================================================
--- logging/log4php/trunk/src/changes/changes.xml (original)
+++ logging/log4php/trunk/src/changes/changes.xml Thu Dec  8 15:10:45 2011
@@ -21,6 +21,7 @@
        </properties>
        <body>
            <release version="2.2.0" date="SVN">
+               <action date="2011-12-08" type="update" issue="LOG4PHP-154" 
dev="Ivan Habunek">Rewritten LoggerAppenderSocket to use a layout.</action>
                <action date="2011-12-04" type="add" issue="LOG4PHP-160" 
dev="Ivan Habunek" due-to="Florian Semm" due-to-email="florian dot semm at gmx 
dot de">Appeneders should use a default layout is no layout is specified in 
configuration</action>
                <action date="2011-10-23" type="add" issue="LOG4PHP-155" 
dev="Ivan Habunek">Created a new layout LoggerLayoutSerialized which formats 
events as serialized objects.</action>
                <action date="2011-10-23" type="fix" issue="LOG4PHP-159" 
dev="Ivan Habunek" due-to="Justin Cherniak" due-to-email="justin dot cherniak 
at gmail dot com">Appenders do not close gracefully if a fatal error 
occurs.</action>

Modified: logging/log4php/trunk/src/main/php/appenders/LoggerAppenderSocket.php
URL: 
http://svn.apache.org/viewvc/logging/log4php/trunk/src/main/php/appenders/LoggerAppenderSocket.php?rev=1211929&r1=1211928&r2=1211929&view=diff
==============================================================================
--- logging/log4php/trunk/src/main/php/appenders/LoggerAppenderSocket.php 
(original)
+++ logging/log4php/trunk/src/main/php/appenders/LoggerAppenderSocket.php Thu 
Dec  8 15:10:45 2011
@@ -19,240 +19,114 @@
  */
 
 /**
- * Serialize events and send them to a network socket.
+ * Appends events to a network socket.
  *
  * This appender can be configured by changing the following attributes:
  * 
- * - locationInfo       - Sets the location info for the xml layout (true or 
false)
- * - log4jNamespace     - Sets the namespace for log4j (true or false)
- * - port               - Sets the port of the socket.
- * - remoteHost         - Sets the remote host
- * - timeout            - Sets the timeout in ms
- * - useXml             - true, if xml should be transmitted.
- *                        false, if a serialized php object should be 
transmitted
- *
- * Parameters are {@link $remoteHost}, {@link $port}, {@link $timeout}, 
- * {@link $locationInfo}, {@link $useXml} and {@link $log4jNamespace}.
- *
- * An example:
- * 
- * {@example ../../examples/php/appender_socket.php 19}
+ * - remoteHost - Target remote host.
+ * - port       - Target port (optional, defaults to 4446).
+ * - timeout    - Connection timeout in seconds (optional, defaults to
+ *                'default_socket_timeout' from php.ini)
  * 
- * {@example ../../examples/resources/appender_socket.properties 18}
+ * The socket will by default be opened in blocking mode.
  * 
  * @version $Revision$
  * @package log4php
  * @subpackage appenders
  */ 
 class LoggerAppenderSocket extends LoggerAppender {
-
-       /**
-        * This appender does not require a layout.
-        */
-       protected $requiresLayout = false;
        
-       /**
-        * @var mixed socket connection resource
+       /** 
+        * Target host.
+        * @see http://php.net/manual/en/function.fsockopen.php 
         */
-       private $sp = false;
+       private $remoteHost;
        
-       /**
-        * Target host. On how to define remote hostaname see 
-        * {@link PHP_MANUAL#fsockopen}
-        * @var string 
-        */
-       private $remoteHost = '';
-       
-       /**
-        * @var integer the network port.
-        */
+       /** Target port */
        private $port = 4446;
        
-       /**
-        * @var boolean get event's location info.
-        */
-       private $locationInfo = false;
+       /** Connection timeout in ms. */
+       private $timeout;
        
-       /**
-        * @var integer connection timeout
-        */
-       private $timeout = 30;
-       
-       /**
-        * @var boolean output events via {@link LoggerXmlLayout}
-        */
-       private $useXml = false;
-       
-       /**
-        * @var boolean forward this option to {@link LoggerXmlLayout}. 
-        *                              Ignored if {@link $useXml} is 
<i>false</i>.
-        */
-       private $log4jNamespace = false;
-
-       /**
-        * @var LoggerXmlLayout
-        */
-       private $xmlLayout = null;
-       
-       /** @var indiciates if this appender should run in dry mode */
-       private $dry = false;
+       // ******************************************
+       // *** Appender methods                   ***
+       // ******************************************
+       
+       /** Override the default layout to use serialized. */
+       public function getDefaultLayout() {
+               return new LoggerLayoutSerialized();
+       }
        
-       /**
-        * Create a socket connection using defined parameters
-        */
        public function activateOptions() {
-               if(!$this->dry) {
-                       $this->sp = @fsockopen($this->getRemoteHost(), 
$this->getPort(), $errno, $errstr, $this->getTimeout());
-                       if ($this->sp === false) {
-                               throw new LoggerException("Could not open 
socket to ".$this->getRemoteHost().":".$this->getPort().": $errstr ($errno)");
-                       }
-               }
-               if($this->getUseXml()) {
-                       $this->xmlLayout = 
LoggerReflectionUtils::createObject('LoggerLayoutXml');
-                       if($this->xmlLayout === null) {
-                               $this->setUseXml(false);
-                       } else {
-                               
$this->xmlLayout->setLocationInfo($this->getLocationInfo());
-                               
$this->xmlLayout->setLog4jNamespace($this->getLog4jNamespace());
-                               $this->xmlLayout->activateOptions();
-                       }                        
+               if (empty($this->remoteHost)) {
+                       $this->warn("Required parameter [remoteHost] not set. 
Closing appender.");
+                       $this->closed = true;
+                       return;
+               }
+       
+               if (empty($this->timeout)) {
+                       $this->timeout = ini_get("default_socket_timeout");
                }
+       
                $this->closed = false;
        }
        
-       public function close() {
-               if($this->closed != true) {
-                       if(!$this->dry and $this->sp !== false) {
-                               fclose($this->sp);
-                       }
+       public function append(LoggerLoggingEvent $event) {
+               $socket = fsockopen($this->remoteHost, $this->port, $errno, 
$errstr, $this->timeout);
+               if ($socket === false) {
+                       $this->warn("Could not open socket to 
{$this->remoteHost}:{$this->port}. Closing appender.");
                        $this->closed = true;
+                       return;
                }
-       }
-
-       public function setDry($dry) {
-               $this->dry = $dry;
-       }
        
-       /**
-        * @return string
-        */
-       public function getHostname() {
-               return $this->getRemoteHost();
+               if (false === fwrite($socket, $this->layout->format($event))) {
+                       $this->warn("Error writing to socket. Closing 
appender.");
+                       $this->closed = true;
+               }
+               fclose($socket);
        }
        
-       /**
-        * @return boolean
-        */
-       public function getLocationInfo() {
-               return $this->locationInfo;
-       } 
-        
-       /**
-        * @return boolean
-        */
-       public function getLog4jNamespace() {
-               return $this->log4jNamespace;
-       }
-
-       /**
-        * @return integer
-        */
-       public function getPort() {
-               return $this->port;
-       }
+       // ******************************************
+       // *** Accessor methods                   ***
+       // ******************************************
        
-       public function getRemoteHost() {
-               return $this->remoteHost;
+       /** Sets the target host. */
+       public function setRemoteHost($hostname) {
+               $this->remoteHost = $hostname;
        }
        
-       /**
-        * @return integer
-        */
-       public function getTimeout() {
-               return $this->timeout;
+       /** Sets the target port */
+       public function setPort($port) {
+               try {
+                       $this->port = LoggerOptionConverter::toIntegerEx($port, 
null);
+               } catch (Exception $ex) {
+                       $this->warn("Invalid value provided for 'port' [$port]. 
Expected an integer. Using default value [{$this->port}].");
+               }
        }
-       
-       /**
-        * @var boolean
-        */
-       public function getUseXml() {
-               return $this->useXml;
-       } 
         
-       public function reset() {
-               $this->close();
-       }
-
-       /**
-        * @param mixed
-        */
-       public function setLocationInfo($flag) {
-               $this->locationInfo = LoggerOptionConverter::toBoolean($flag, 
$this->getLocationInfo());
-       } 
-
-       /**
-        * @param mixed
-        */
-       public function setLog4jNamespace($flag) {
-               $this->log4jNamespace = LoggerOptionConverter::toBoolean($flag, 
$this->getLog4jNamespace());
-       } 
-                       
-       /**
-        * @param integer
-        */
-       public function setPort($port) {
-               $port = LoggerOptionConverter::toInt($port, 0);
-               if($port > 0 and $port < 65535) {
-                       $this->port = $port;    
+       /** Sets the timeout. */
+       public function setTimeout($timeout) {
+               try {
+                       $this->timeout = 
LoggerOptionConverter::toIntegerEx($timeout);
+               } catch (Exception $ex) {
+                       $value = var_export($timeout);
+                       $default = var_export($this->timeout);
+                       $this->warn("Invalid value provided for 'timeout' 
[$value]. Expeceted an integer. Using default value [$default].");
                }
        }
        
-       /**
-        * @param string
-        */
-       public function setRemoteHost($hostname) {
-               $this->remoteHost = $hostname;
+       /** Returns the target host. */
+       public function getRemoteHost() {
+               return $this->getRemoteHost();
        }
        
-       /**
-        * @param integer
-        */
-       public function setTimeout($timeout) {
-               $this->timeout = LoggerOptionConverter::toInt($timeout, 
$this->getTimeout());
+       /** Returns the target port. */
+       public function getPort() {
+               return $this->port;
        }
        
-       /**
-        * @param mixed
-        */
-       public function setUseXml($flag) {
-               $this->useXml = LoggerOptionConverter::toBoolean($flag, 
$this->getUseXml());
-       } 
- 
-       public function append(LoggerLoggingEvent $event) {
-               if($this->sp || $this->dry) {
-                       if($this->getLocationInfo()) {
-                               $event->getLocationInformation();
-                       }
-               
-                       if(!$this->getUseXml()) {
-                               $sEvent = serialize($event);
-                               if(!$this->dry) {
-                                       fwrite($this->sp, $sEvent, 
strlen($sEvent));
-                               } else {
-                                       echo "DRY MODE OF SOCKET APPENDER: 
".$sEvent;
-                               }
-                       } else {
-                               if(!$this->dry) {
-                                       fwrite($this->sp, 
$this->xmlLayout->format($event));
-                               } else {
-                                       echo "DRY MODE OF SOCKET APPENDER: 
".$this->xmlLayout->format($event);
-                               }
-                       }
-
-                       // not sure about it...
-                       if(!$this->dry) {
-                               fflush($this->sp);
-                       }
-               }
+       /** Returns the timeout */
+       public function getTimeout() {
+               return $this->timeout;
        }
 }

Modified: logging/log4php/trunk/src/site/xdoc/docs/appenders/socket.xml
URL: 
http://svn.apache.org/viewvc/logging/log4php/trunk/src/site/xdoc/docs/appenders/socket.xml?rev=1211929&r1=1211928&r2=1211929&view=diff
==============================================================================
--- logging/log4php/trunk/src/site/xdoc/docs/appenders/socket.xml (original)
+++ logging/log4php/trunk/src/site/xdoc/docs/appenders/socket.xml Thu Dec  8 
15:10:45 2011
@@ -25,9 +25,11 @@
        <body>
                <section name="LoggerAppenderSocket">
                
-                       <p><code>LoggerAppenderSocket</code> serializes log 
events and sends them to a network socket.</p>
+                       <p><code>LoggerAppenderSocket</code> appends to a 
network socket.</p>
                        
-                       <p>This appender does not require a layout.</p>
+                       <p>Unlike most other appenders, the default layout for 
this appender is <code>LoggerLayoutSerialized</code>.</p>
+                       
+                       <p>Prior to version <code>2.2</code>, a layout was not 
required.</p>
                        
                        <subsection name="Options">
                                <p>The following options are available:</p>
@@ -63,41 +65,16 @@
                                                        <td>timeout</td>
                                                        <td>integer</td>
                                                        <td>No</td>
-                                                       <td>30</td>
+                                                       
<td><code>ini_get('default_socket_timeout')</code></td>
                                                        <td>Timeout in ms.</td>
                                                </tr>
-                                               <tr>
-                                                       <td>useXml</td>
-                                                       <td>boolean</td>
-                                                       <td>No</td>
-                                                       <td>false</td>
-                                                       <td>If set to 
<em>true</em> the appender will sent the event formatted in XML. Otherwise, 
-                                                       the appender will send 
the event as a serialized PHP object.</td>
-                                               </tr>
-                                               <tr>
-                                                       <td>locationInfo</td>
-                                                       <td>boolean</td>
-                                                       <td>No</td>
-                                                       <td>false</td>
-                                                       <td>Whether location 
info is included for the XML event format. Ignored if XML format is not 
used.</td>
-                                               </tr>
-                                               <tr>
-                                                       <td>log4jNamespace</td>
-                                                       <td>boolean</td>
-                                                       <td>No</td>
-                                                       <td>false</td>
-                                                       <td>In XML format, 
<code>log4php</code> namespace is used by default. If set to true, 
-                                                       <code>log4j</code> 
namespace will be used instead.</td>
-                                               </tr>
                                        </tbody>
                                </table>
-                               
                        </subsection>
                                
                        <subsection name="Examples">
                                
-                               <p>In this example, log events are sent to 
localhost:4242, using the serialized format. The host 
-                               will recieve a serialized LoggerLoggingEvent 
object.</p>
+                               <p>In this example, log events are sent to 
localhost:4242, using the default (serialized) layout.</p>
                                
                                <p>XML configuration:</p>
                                        

Modified: 
logging/log4php/trunk/src/test/php/appenders/LoggerAppenderSocketTest.php
URL: 
http://svn.apache.org/viewvc/logging/log4php/trunk/src/test/php/appenders/LoggerAppenderSocketTest.php?rev=1211929&r1=1211928&r2=1211929&view=diff
==============================================================================
--- logging/log4php/trunk/src/test/php/appenders/LoggerAppenderSocketTest.php 
(original)
+++ logging/log4php/trunk/src/test/php/appenders/LoggerAppenderSocketTest.php 
Thu Dec  8 15:10:45 2011
@@ -6,16 +6,16 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- * 
- * @category   tests   
+ *
+ * @category   tests
  * @package    log4php
  * @subpackage appenders
  * @license    http://www.apache.org/licenses/LICENSE-2.0 Apache License, 
Version 2.0
@@ -27,66 +27,123 @@
  * @group appenders
  */
 class LoggerAppenderSocketTest extends PHPUnit_Framework_TestCase {
-        
+
+       /** Port on which the socket server will run. */
+       const SOCKET_PORT = 12345;
+
+       /** The socket server process resource. */
+       private $server;
+       
+       /** The pipes array for the server process. */
+       private $pipes;
+       
+       public function setUp() {
+               Logger::clear();
+       }
+       
+       public function tearDown() {
+               Logger::clear();
+       }
+       
        public function testRequiresLayout() {
                $appender = new LoggerAppenderSocket();
-               self::assertFalse($appender->requiresLayout());
+               self::assertTrue($appender->requiresLayout());
        }
        
-       public function testSocketSerialized() {
-               $appender = new LoggerAppenderSocket("myname ");
+       public function testLogging()
+       {
+               Logger::configure(array(
+                   'appenders' => array(
+                       'default' => array(
+                           'class' => 'LoggerAppenderSocket',
+                           'params' => array(
+                               'remoteHost' => 'localhost',
+                               'port' => self::SOCKET_PORT
+                           ),
+                           'layout' => array(
+                               'class' => 'LoggerLayoutSimple'
+                           )
+                       ),
+                   ),
+                   'rootLogger' => array(
+                       'appenders' => array('default'),
+                   ),
+               ));
+
+               $this->startServer();
+               
+               $logger = Logger::getLogger("myLogger");
+               $logger->trace("This message is a test");
+               $logger->debug("This message is a test");
+               $logger->info("This message is a test");
+               $logger->warn("This message is a test");
+               $logger->error("This message is a test");
+               $logger->fatal("This message is a test");
                
-               $layout = new LoggerLayoutSimple();
-               $appender->setLayout($layout);
-               $appender->setDry(true);
-//             $appender->setUseXml(true);
-               $appender->activateOptions();
-               $event = new LoggerLoggingEvent("LoggerAppenderSocketTest", new 
Logger("TEST"), LoggerLevel::getLevelError(), "testmessage");
-                
-               ob_start();
-               $appender->append($event);
-               $v = ob_get_contents();
-               ob_end_clean();
-               $s = serialize($event);
-               
-               $e = "DRY MODE OF SOCKET APPENDER: ".$s;
-               self::assertEquals($e, $v);
-    }
-    
-    public function testSocketXml() {
-               $appender = new LoggerAppenderSocket("myname ");
-               
-               $appender->setDry(true);
-               $appender->setUseXml(true);
-               $appender->setLocationInfo(true);
-               $appender->activateOptions();
-               $event = new LoggerLoggingEvent("LoggerAppenderSocketTest", new 
Logger("TEST"), LoggerLevel::getLevelError(), "testmessage");
-                
-               ob_start();
-               $appender->append($event);
-               $v = ob_get_contents();
-               ob_end_clean();
-               
-               $layout = new LoggerLayoutXml();
-               $layout->setLog4jNamespace(false);
-               $layout->activateOptions();
-               $a = $layout->format($event);
-               $e = "DRY MODE OF SOCKET APPENDER: ".$a;
-               self::assertEquals($e, $v);
-    }
-    
-    /** Tests Exception due to unreachable remote host.
-     * 
-     * @expectedException LoggerException
-     */
-    public function testSocketProblem() {
-        $appender = new LoggerAppenderSocket("myname ");
-        $appender->setDry(false);
-        $appender->setRemoteHost("does.not.exists");
-        $appender->setPort(1234);
-        $appender->activateOptions();
-        $event = new LoggerLoggingEvent("LoggerAppenderSocketTest", new 
Logger("TEST"), LoggerLevel::getLevelError(), "testmessage");
-        
-        $appender->append($event);
-    }
+               $actual = $this->getPlayback();
+               $this->stopServer();
+               
+               $expected = "DEBUG - This message is a test" . 
+                           "INFO - This message is a test" . 
+                           "WARN - This message is a test" . 
+                           "ERROR - This message is a test" . 
+                           "FATAL - This message is a test";
+
+               $this->assertEquals($expected, $actual);
+       }
+       
+       /** Starts a socket server in a separate process. */
+       private function startServer() {
+               $serverLog = PHPUNIT_TEMP_DIR . '/socketServer.log';
+               $descriptorspec = array(
+                       0 => array("pipe", "r"),  // stdin
+                       1 => array("file", $serverLog, "a"),// stdout
+                       2 => array("file", $serverLog, "a") // stderr
+               );
+
+               $cmd = "php " . dirname(__FILE__) . '/socketServer.php';
+               $this->server = proc_open($cmd, $descriptorspec, $this->pipes);
+               if ($this->server === false) {
+                       throw new Exception("Failed starting the socket server 
process.");
+               }
+               
+               // Sleep a bit to allow server to start
+               usleep(200000);
+               
+               // Verify the server is running
+               $status = proc_get_status($this->server);
+               if (!$status['running']) {
+                       throw new Exception("Socket server process failed to 
start. Check the log at [$serverLog].");
+               }
+       }
+       
+       /** Sends a message to the socket server and returns the reply. */
+       private function socketSend($msg) {
+               $sock = fsockopen('localhost', self::SOCKET_PORT, $errno, 
$errstr);
+               if ($sock === false) {
+                       throw new Exception("Unable to open socket. Error: 
[$errno] $errstr");  
+               }
+               
+               fputs($sock, "$msg\n");
+               $reply = '';
+               while(!feof($sock)) {
+                       $reply .= fgets($sock);
+               }
+               fclose($sock);
+               return trim($reply);
+       }
+       
+       /** Retrieves a playback of all sent messages from the socket server. */
+       private function getPlayback() {
+               return $this->socketSend('playback');
+       }
+       
+       /** Stops the socket server and closes the process. */
+       private function stopServer() {
+               $this->socketSend('shutdown');
+               foreach($this->pipes as $pipe) {
+                       fclose($pipe);
+               }
+               proc_close($this->server);
+       }
 }

Added: logging/log4php/trunk/src/test/php/appenders/socketServer.php
URL: 
http://svn.apache.org/viewvc/logging/log4php/trunk/src/test/php/appenders/socketServer.php?rev=1211929&view=auto
==============================================================================
--- logging/log4php/trunk/src/test/php/appenders/socketServer.php (added)
+++ logging/log4php/trunk/src/test/php/appenders/socketServer.php Thu Dec  8 
15:10:45 2011
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @category   tests
+ * @package    log4php
+ * @subpackage appenders
+ * @license    http://www.apache.org/licenses/LICENSE-2.0 Apache License, 
Version 2.0
+ * @version    SVN: $Id$
+ * @link       http://logging.apache.org/log4php
+ * 
+ * A simple socket server used in LoggerAppenderSocketTest.
+ */
+
+// Port on which to start the server
+define('SERVER_PORT', 12345);
+
+// Prevent hangs
+set_time_limit(0);
+
+// Create a socket
+$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+if ($sock === false) {
+       die("Failed creating socket: " . socket_strerror(socket_last_error()));
+}
+
+if (socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1) === false) {
+       die("Failed setting socket options: " . 
socket_strerror(socket_last_error()));
+}
+
+if (socket_bind($sock, 'localhost', SERVER_PORT) === false) {
+       die("Failed binding socket: " . socket_strerror(socket_last_error()));
+}
+
+if (socket_listen($sock, 100) === false) {
+       die("Failed binding socket: " . socket_strerror(socket_last_error()));
+}
+
+socket_getsockname($sock, $addr, $port);
+myLog("Server Listening on $addr:$port");
+
+// Buffer which will store incoming messages
+$playback = "";
+
+while(true) {
+       myLog("Waiting for incoming connections...");
+       
+       $msgsock = socket_accept($sock);
+       if ($msgsock === false) {
+               myLog("Failed accepting a connection: " . 
socket_strerror(socket_last_error()));
+               break;
+       }
+       
+       $buf = socket_read($msgsock, 2048, PHP_NORMAL_READ);
+
+       myLog('Received: "' . trim($buf) . '"');
+       
+       // Shutdown command
+       if (trim($buf) == 'shutdown') {
+               myLog("Shutting down.");
+               socket_close($msgsock);
+               break;
+       } 
+       // Playback command
+       else if (trim($buf) == 'playback') {
+               myLog("Returning playback: \"$playback\"");
+               socket_write($msgsock, $playback);
+       } 
+       // Default: add to playback buffer
+       else {
+               $playback .= trim($buf); 
+       }
+       
+       socket_close($msgsock);
+}
+
+myLog("Closing socket.");
+socket_close($sock);
+
+function myLog($msg) {
+       echo date("Y-m-d H:i:s") . " $msg\n";
+}
+
+?>


Reply via email to