Source for file Multiprocess.php
Documentation is available at Multiprocess.php
* Originally coded by the author Stephan Schmidt
* and committed to PEAR repository.
* Deep modifications was been made since that day...
* Into PEAR you can actually found the base class (Server.php)
* the handler base class (Handler.php) and the sequential driver (Sequential.php)
* I developed both multiprocess driver and Multi Processing Modules (actually only preforking)
* specifically for phplet project.
* Hope this stuff can be committed to PEAR one day!
* @author Stephan Schmidt <schst@php.net>
require_once 'PHP/Fork.php';
require_once 'Net/Server/Driver.php';
require_once 'Net/Server/Driver/Multiprocess/remoteConsole.php';
require_once 'Net/Server/Driver/Multiprocess/Processor.php';
* set maximum amount of simultaneous connections
* that's to say the maximum number of listener processes
* that this server can handle
$this->_numThreads = $maxClients;
* set the initial number of listener processes
$this->_startPool = $dim;
* set the maximun time a process can be sleeping
* (without serving any request) before MPM kill it
* NOT USED AT THIS MOMENT
$this->_maxIdleTime = $secs;
* set the MPM layout for this server
* (only preforkg avaible for now)
* set the console class for this server
* @param string $classname
$this->_console = $classname;
die ('Needs pcntl extension to fork processes.');
die ("Could not create socket.");
if (!@socket_bind($this->initFD, $this->domain, $this->port)) {
die ("Could not bind socket to " . $this->domain . " on port " . $this->port . " (" . $error . ").");
// listen on selected port
die ("Could not listen (" . $error . ").");
$this->callbackObj->onStart ();
$this->_setDefaultOptions ();
$mpmDriverFile = 'Net/Server/Driver/Multiprocess/MPM-' . $this->_mpm . '.php';
if (!@include_once $mpmDriverFile) {
die ('Unknown MPM ' . $mpmDriverFile);
// starting pool of processors...
for ($i = 0; $i < $this->_startPool; $i++ ) {
$this->_threadPool[$i] = & new Net_Server_Thread_Processor ($i, $this);
$this->_threadPool[$i]->start ();
print ("Started Processor " . $i . " with PID " . $this->_threadPool[$i]->getPid () . "\n");
$this->_mpmObj = & new MPM ($this->_threadPool, $this);
print ("Started MPM with PID " . $this->_mpmObj->getPid () . "\n");
// destroy the listening primar socket, it's unuseful at this point
$consoleClassName = $this->_console;
if (!@include_once ('Net/Server/Driver/Multiprocess/'. $consoleClassName. '.php')) {
die ('Unknown console ' . $consoleClassName);
$this->_consoleObj = & new $consoleClassName($this);
$this->_consoleObj->start ();
print ("Started remote console with PID " . $this->_consoleObj->getPid () . "\n");
* check, whether a client is still connected
* @param integer $id client id
* @return boolean $connected true if client is connected, false otherwise
* get current amount of clients
* @return int $clients amount of clients
$overview = $this->_mpmObj->getProcOverview ();
return $overview['working'];
* @param int $clientId ID of the client
* @param string $data data to send
* @param boolean $debugData flag to indicate whether data that is written to socket should also be sent as debug message
function sendData($clientId, $data, $debugData = true )
if (!isset ($this->clientFD[$clientId]) || $this->clientFD[$clientId] == null ) {
return $this->raiseError(" Client $clientId does not exist. (193)" );
* send data to all clients
* @param string $data data to send
* @param array $exclude client ids to exclude
* get current information about a client
* @param int $i ID of the client
* @return array $info information about the client
if (!isset ($this->clientFD[$i]) || $this->clientFD[$i] == null ) {
return $this->raiseError("Client does not exist.(226)");
return $this->clientInfo[$i];
* close connection to a client
* @param int $i internal ID of the client
if (!isset ($this->clientFD[$i])) {
return $this->raiseError("Connection already has been closed.");
$this->callbackObj->onClose ($i);
"Closed connection from " . $this->clientInfo[$i]["host"]
. " on port " . $this->clientInfo[$i]["port"]
$this->clientFD[$i] = null;
unset ($this->clientInfo[$i]);
* ---------------------------- ATTENTION -------------------------------------
* On multiprocess layouts stopping the server ==> stopping all processes
* that are listening on server port; we generally can't do this operation
* from the same server instance, because it only knows of the existence of processes
* that it forked at start(). This start pool is equivalent to running pool in every
* moment only if we're running the MPM-static.
* With more complex MPM like the pre-forking one the process responsible for forking
* new listeners at run-time is MPM, so we must make a call to it in order
* to stop all forked processes.
* Of course if we have a running MPM and a running console, stopping the server
* requires stopping them too.
$this->callbackObj->onShutdown ();
// this always should return true, we use PHP_FORK_RETURN_METHOD because
// we want to wait until all processes are really stopped...
if ($this->_mpmObj->stopAllProcesses (array (''), PHP_FORK_RETURN_METHOD )) {
print "Stopping " . $this->_mpmObj->getName () . "\n";
print "Exiting from console...\n";
print "Error stopping mpm\n";
$this->_consoleObj->stop ();
* set some default options that are needed to run
* a multiprocess server; usually we override this
function _setDefaultOptions ()
if (!isset ($this->_numThreads)) {
if (!isset ($this->_startPool)) {
if (!isset ($this->_maxIdleTime)) {
$this->_maxIdleTime = 60;
if (!isset ($this->_mpm)) {
if (!isset ($this->_console)) {
$this->_console = "remoteConsole";
Documentation generated on Mon, 11 Mar 2019 15:47:10 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|