Skip to content

Instantly share code, notes, and snippets.

@igorw
Created July 7, 2012 00:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save igorw/3063615 to your computer and use it in GitHub Desktop.
Save igorw/3063615 to your computer and use it in GitHub Desktop.
<?php
class Server
{
public $master;
public $read = [];
public $write = [];
public $writeBuf = [];
public function listen($address)
{
$this->master = stream_socket_server($address);
stream_set_blocking($this->master, 0);
$this->read[] = $this->master;
$this->loop();
}
public function loop()
{
while (true) {
$readable = $this->read ?: null;
$writable = $this->write ?: null;
$except = null;
if (!stream_select($readable, $writeable, $except, 1)) {
continue;
}
if ($readable) {
$this->processReadableStreams($readable);
}
if ($writable) {
$this->processWritableStreams($writable);
}
}
}
public function processReadableStreams($readable)
{
foreach ($readable as $stream) {
if ($this->master === $stream) {
$this->acceptConnection($stream);
} else {
$this->processIncomingData($stream);
}
}
}
public function acceptConnection($master)
{
$conn = stream_socket_accept($master, 0);
stream_set_blocking($conn, 0);
$this->read[] = $conn;
}
public function processIncomingData($conn)
{
$data = fread($conn, 1024);
if ('' === $data) {
fclose($conn);
$index = array_search($conn, $this->read);
unset($this->read[$index]);
$index = array_search($conn, $this->write);
if (false !== $index) {
unset($this->write[$index]);
}
} else {
$this->enqueueData($conn, $data);
}
}
public function enqueueData($conn, $data)
{
$id = (int) $conn;
if (!isset($this->writeBuf[$id])) {
$this->writeBuf[$id] = '';
}
$this->writeBuf[$id] .= $data;
$this->write[] = $conn;
}
public function processWritableStreams($writable)
{
foreach ($writable as $stream) {
$this->writeOutgoingData($stream);
}
}
public function writeOutgoingData($conn)
{
$id = (int) $conn;
$data = $this->writeBuf[$id];
$written = fwrite($conn, $data);
$this->writeBuf[$id] = (string) substr($this->writeBuf[$id], $written);
if ('' === $this->writeBuf[$id]) {
$index = array_search($conn, $this->write);
unset($this->write[$index]);
}
}
}
$server = new Server();
$server->listen('tcp://127.0.0.1:1337');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment