Skip to content

Instantly share code, notes, and snippets.

@ackintosh
Created April 14, 2013 08:29
Show Gist options
  • Save ackintosh/5381925 to your computer and use it in GitHub Desktop.
Save ackintosh/5381925 to your computer and use it in GitHub Desktop.
MultiClient TCP Server in PHP
<?php
$f = function ($input) {
echo "input: " . $input;
};
try {
// ポート4000、待機プロセス数2
MultiClientTCPServer::instance(4000, 2)->run($f);
} catch (RuntimeException $e) {
die('error: ' . $e->getMessage());
}
class MultiClientTCPServer
{
private $process_stack = array();
private $concurrency;
private $port;
private function __construct($port, $concurrency)
{
$this->port = $port;
$this->concurrency = $concurrency;
}
public static function instance($port = 4000, $concurrency = 5)
{
return new self($port, $concurrency);
}
public function run($function_for_child)
{
$socket = socket_create_listen($this->port);
while (true) {
if (count($this->process_stack) >= $this->concurrency) {
$stopped_pid = pcntl_waitpid(-1, $status, WUNTRACED);
unset($this->process_stack[$stopped_pid]);
}
$pid = pcntl_fork();
switch ($pid) {
case -1:
throw new RuntimeException('can not fork process');
break;
case 0:
// child process
$client = socket_accept($socket);
while (true) {
$input = socket_read($client, 1024);
if (preg_match('/^exit;/', $input) === 1) break;
$result = $function_for_child($input);
}
socket_close($client);
exit;
break;
default:
// parent process
$this->process_stack[$pid] = true;
break;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment