Source for file dpserver.php
Documentation is available at dpserver.php
* Provides 'DpServer' class to answer normal and AJAX requests from web clients
* DutchPIPE version 0.4; PHP version 5
* LICENSE: This source file is subject to version 1.0 of the DutchPIPE license.
* If you did not receive a copy of the DutchPIPE license, you can obtain one at
* http://dutchpipe.org/license/1_0.txt or by sending a note to
* license@dutchpipe.org, in which case you will be mailed a copy immediately.
* @author Lennert Stock <ls@dutchpipe.org>
* @copyright 2006, 2007 Lennert Stock
* @license http://dutchpipe.org/license/1_0.txt DutchPIPE License
* @version Subversion: $Id: dpserver.php 278 2007-08-19 22:52:25Z ls $
* @link http://dutchpipe.org/manual/package/DutchPIPE
* @see dpclient.php, dpuniverse.php
/* Shows all possible errors */
* A DutchPIPE server to answer normal and AJAX requests from web clients
* The DutchPIPE server which can be started and then keeps running while
* accepting socket connections. Waits for and accepts socket requests from
* users connected through dpclient.php, and returns output to dpclient.php,
* which returns it to the end user. If there are 10 users on the site, it will
* loop through the main code for each user at a time.
* To answer each request, the server passes the request on to the persistent
* DbUniverse object, where the real processing takes place.
* @author Lennert Stock <ls@dutchpipe.org>
* @copyright 2006, 2007 Lennert Stock
* @license http://dutchpipe.org/license/1_0.txt DutchPIPE License
* @version Release: 0.2.1
* @link http://dutchpipe.org/manual/package/DutchPIPE
* @see dpclient.php, dpuniverse.php
* @var resource The socket the server has opened to a client
* @var resource Used to show server status info on the cmd line
private $mShowedStatusHeader = 0;
* Used to show server status info based on getrusage, start "user" time of
* @var resource Start 'user' time of script
* Used to show server status info based on getrusage, start "system" time
* @var resource Start "system" time of script
* Sets up the server at object creation time based on your settings
* @param string $iniFile Path to a dpserver-ini.php like file
/* Used by showStatus() further below */
$this->mUtimeBefore = (int) $rusage["ru_utime.tv_sec"] * 1e6 +
(int) $rusage["ru_utime.tv_usec"];
$this->mStimeBefore = (int) $rusage["ru_stime.tv_sec"] * 1e6 +
(int) $rusage["ru_stime.tv_usec"];
/* Get the server settings */
? 'disabled' : 'enabled') . '.php');
/* Allow the script to hang around waiting for connections */
/* See what we're getting as it comes in */
* Starts the DutchPIPE server, using a specific 'universe' object
* Also see: http://www.php.net/sockets
* @param object &$universe An instance of DpUniverse
/* Check if the server is already running */
/* :KLUDGE: should be improved */
//die(dp_text("Cannot start server: server already running\n"));
/* Initialize the server, first create a socket */
if (FALSE === ($socket = socket_create(AF_UNIX, SOCK_STREAM, 0))) {
"socket_create(): unable to create socket [%u]: %s\n"),
/* Bind the socket to a file, for example /tmp/dutchpipesock */
"socket_bind() unable to bind socket [%u]: %s\n"),
"Cannot start server: reason: chmod on %s failed\n"),
/* Initialize the server, first create a socket */
"socket_create(): unable to create socket [%u]: %s\n"),
/* Reuse the port in case it was not properly closed */
/* Bind the socket to a file, for example /tmp/dutchpipesock */
"socket_bind() unable to bind socket [%u]: %s\n"),
die(dp_text("Invalid socket protocol.\n"));
/* Start listening to the socket which dpclient.php talks to */
/* Accept connections and loop for each request */
* We got a connection with a user client through dpclient.php,
* dpclient.php should send some serialized arrays with variables.
* These are the PHP global $_SERVER, $_COOKIE, ... arrays.
* All client info, including input and AJAX parameters, are send
/* Read in what dpclient.php is telling us in chunks */
"socket_read(): failure [%u]: %s\n"),
/* This can be used to shutdown the server */
if ($buf == 'shutdown') {
* Read the 2KB blocks until dpclient.php sends us a 'quit'
/* Read in what dpclient.php is telling us in chunks */
"socket_read(): failure [%u]: %s\n"),
/* This can be used to shutdown the server */
* Read the 2KB blocks until dpclient.php sends us a 'quit'
//$allbuf = dp_substr($allbuf, 0, dp_strlen($allbuf - 4));
/* Check for invalid input from dpclient.php */
|| FALSE === ($pos1 = dp_strpos($allbuf, "<vars>"))
|| FALSE === ($pos2 = dp_strpos($allbuf, "</vars>"))
echo 'allbuf: ' . $allbuf . "\n";
* Cut out and unserialize the three global PHP vars
//$handle = fopen('/tmp/dpserver.log', 'a');
//fwrite($handle, sprintf(dp_text("No unserialize: %s\n"),
$__SERVER = $__SESSION = $__COOKIE = $__GET = $__POST =
list ($__SERVER, $__SESSION, $__COOKIE, $__GET, $__POST,
* Pass on the request to the universe object. The universe
* object can response by calling tellCurrentDpUserRequest()
$universe->handleCurrentDpUserRequest($this, $__SERVER,
$__SESSION, $__COOKIE, $__GET, $__POST, $__FILES);
* :KLUDGE: Shows server status once in a while. The ticks
* system or external cron triggered calls should be used in the
if (1 === mt_rand(1, 2 + $universe->getNrOfUsers())) {
$this->_showStatus($universe);
* Closes the socket when the server is destroyed.
* Tells a string to the current user request through dpclient.php
* Called from 'the universe' to talk back to the client, messages are
* typically XML with something like '<message>Lennert says: hi</message>'.
* @param string $talkback String to send to current user client
* Shows some server info on the command line
* @param object &$universe An instance of DpUniverse
private function _showStatus(&$universe)
$universe->showStatusMemoryGetUsage();
$this->_showStatusMemoryGetrusage($universe);
* Shows a line with getrusage info, see man getrusage
* @param object &$universe An instance of DpUniverse
private function _showStatusMemoryGetrusage(&$universe)
$utime_after = (int) $dat["ru_utime.tv_sec"]* 1e6 +
(int) $dat["ru_utime.tv_usec"];
$stime_after = (int) $dat["ru_stime.tv_sec"]* 1e6 +
(int) $dat["ru_stime.tv_usec"];
$dat["ru_utime"] = number_format(($utime_after - $this->mUtimeBefore) /
$dat["ru_stime"] = number_format(($stime_after - $this->mStimeBefore) /
$dat["ru_maxrss"] = $dat["ru_maxrss"] . 'kb';
unset ($dat['ru_oublock']);
unset ($dat['ru_inblock']);
unset ($dat['ru_nsignals']);
unset ($dat['ru_utime.tv_sec']);
unset ($dat['ru_utime.tv_usec']);
unset ($dat['ru_stime.tv_sec']);
unset ($dat['ru_stime.tv_usec']);
if (0 === (int) $this->mShowedStatusHeader) {
foreach ($keys as $i => $k) {
$this->mShowedStatusHeader = 30;
$this->mShowedStatusHeader-- ;
|