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.
-
-
Save igorw/4394209 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 = new React\EventLoop\StreamSelectLoop(); | |
$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; | |
}); | |
/* | |
* Send a message to the server every now and then to imitate | |
* a client talking with a server | |
*/ | |
$loop->addPeriodicTimer(2, function($timer) 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->cancelTimer($timer); | |
return; | |
} | |
$conn->write('The time is: ' . time() . "\n"); | |
}); | |
print "Starting\n"; | |
$loop->run(); |
This file contains hidden or 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
{ | |
"require": { | |
"react/socket": "0.2.*" | |
} | |
} |
This file contains hidden or 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; | |
} | |
} | |
class SimpleClient extends React\Stream\ReadableStream | |
{ | |
public function thanks() | |
{ | |
$this->emit('data', array("250 Thanks!\n")); | |
} | |
} | |
$loop = React\EventLoop\Factory::create(); | |
$socket = new React\Socket\Server($loop); | |
/** | |
* Basic container for all the connection objects | |
*/ | |
$clients = 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 ($clients) | |
{ | |
// create parser and client | |
$parser = new SimpleParser(); | |
$client = new SimpleClient(); | |
// set up client storage | |
$clients->attach($client); | |
$connection->on('end', function () use ($clients, $client) { | |
$clients->detach($client); | |
}); | |
// After the parser prepares a frame, we can do something with it and respond | |
$parser->on('frame', function($frame) use ($client) | |
{ | |
print 'Client: ' . $frame . "\n"; | |
$client->thanks(); | |
}); | |
// Forward all data to the parser | |
// and from client to connection | |
$connection->pipe($parser); | |
$client->pipe($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