logging-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ihabu...@apache.org
Subject svn commit: r1211929 - in /logging/log4php/trunk/src: changes/changes.xml main/php/appenders/LoggerAppenderSocket.php site/xdoc/docs/appenders/socket.xml test/php/appenders/LoggerAppenderSocketTest.php test/php/appenders/socketServer.php
Date Thu, 08 Dec 2011 15:10:46 GMT
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";
+}
+
+?>



Mime
View raw message