In this example a client connects to a server and sends the current time (a message). Which the server then hands to a parser, then replies too.
Last active
December 10, 2015 06:18
-
-
Save xeoncross/4394094 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require __DIR__.'/../vendor/autoload.php'; | |
$loop = React\EventLoop\Factory::create(); | |
$client = stream_socket_client('tcp://127.0.0.1:4000'); | |
$conn = new React\Socket\Connection($client, $loop); | |
/** | |
* When the server responds we need to do something | |
*/ | |
$conn->on('data', function ($data) use ($conn) | |
{ | |
print "Server: " . $data . "\n"; | |
}); | |
/* | |
* Send a message to the server every now and then to imitate | |
* a client talking with a server | |
*/ | |
$loop->addPeriodicTimer(2, function() use ($conn, $loop) | |
{ | |
$random = mt_rand(1,5); | |
// Randomly finish talking to the server and end the script | |
if($random === 1) | |
{ | |
// Done here | |
$conn->write("QUIT\n"); | |
$conn->end(); | |
$loop->stop(); | |
return; | |
} | |
$conn->write('The time is: ' . time() . "\n"); | |
}); | |
print "Starting\n"; | |
$loop->run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require __DIR__.'/../vendor/autoload.php'; | |
class SimpleParser extends React\Stream\WritableStream | |
{ | |
private $buffer = ''; | |
public function write($data) | |
{ | |
$chunk = $this->buffer.$data; | |
/* | |
* Useally there is a marker in the protocal like a newline or something | |
* (IRC, ZMQ, SMTP, etc...) | |
*/ | |
if (false !== strpos($chunk, "\n")) | |
{ | |
$frames = explode("\n", $chunk); | |
// This last part is still an unfinished chunk of the next set of parts | |
$chunk = array_pop($frames); | |
// Now is your chance to do something with this | |
foreach ($frames as $frame) | |
{ | |
$this->emit('frame', (array) $frame); | |
} | |
} | |
$this->buffer = $chunk; | |
} | |
} | |
$loop = React\EventLoop\Factory::create(); | |
$socket = new React\Socket\Server($loop); | |
/** | |
* Basic container for all the connection objects | |
*/ | |
$conns = new \SplObjectStorage(); | |
/** | |
* The socket server creates a new React\Socket\Connection object for each new connection. | |
* This new connection object extends React\Stream\Stream and so provides both a read/write | |
* interface to the connected client | |
* | |
* @see https://github.com/reactphp/stream/blob/master/Stream.php | |
* @see https://github.com/reactphp/react/blob/master/src/React/Socket/Server.php | |
*/ | |
$socket->on('connection', function ($connection) use ($conns) | |
{ | |
// Attach it to our storage object | |
$conns->attach($connection); | |
// Setup the chat parser | |
$parser = new SimpleParser(); | |
// After the parser prepares a frame, we can do something with it and respond | |
$parser->on('frame', function($frame) use ($connection) | |
{ | |
print 'Client: ' . join('', $frame) . "\n"; | |
$connection->write('250 Thanks!'); | |
}); | |
// Forward all data to the parser | |
$connection->pipe($parser); | |
/* Or does it go here? | |
$connection->on('frame', function ($frame) use ($connection) | |
{ | |
print 'Client: ' . join('', $frame) . "\n"; | |
$connection->write('250 Thanks!'); | |
}); | |
*/ | |
$connection->on('end', function () use ($conns, $connection) { | |
$conns->detach($connection); | |
}); | |
}); | |
/* | |
* Just print out some memory information | |
*/ | |
$loop->addPeriodicTimer(60, function() | |
{ | |
$memory = memory_get_usage() / 1024; | |
$formatted = number_format($memory, 3) . 'K'; | |
echo "Memory: $formatted\n"; | |
}); | |
echo "Starting\n"; | |
$socket->listen(4000); | |
$loop->run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment