public function pause() { if ($this->oldMode !== null) { // Reset stty so it behaves normally again shell_exec(sprintf('stty %s', $this->oldMode)); $this->oldMode = null; parent::pause(); } }
public function __construct(Stream $stream, LoopInterface $loop) { $this->stream = $stream->stream; $this->decorating = $stream; $this->loop = $loop; $stream->on('error', function ($error) { $this->emit('error', [$error, $this]); }); $stream->on('end', function () { $this->emit('end', [$this]); }); $stream->on('close', function () { $this->emit('close', [$this]); }); $stream->on('drain', function () { $this->emit('drain', [$this]); }); $stream->pause(); $this->resume(); }
public function toggle(Stream $stream, $toggle) { // pause actual stream instance to continue operation on raw stream socket $stream->pause(); // TODO: add write() event to make sure we're not sending any excessive data $deferred = new Deferred(); // get actual stream socket from stream instance $socket = $stream->stream; $toggleCrypto = function () use($socket, $deferred, $toggle) { $this->toggleCrypto($socket, $deferred, $toggle); }; $this->loop->addWriteStream($socket, $toggleCrypto); $this->loop->addReadStream($socket, $toggleCrypto); $toggleCrypto(); return $deferred->promise()->then(function () use($stream) { $stream->resume(); return $stream; }, function ($error) use($stream) { $stream->resume(); throw $error; }); }
// with random colors: // $ phpunit --color=always | php random-colors.php use React\Stream\Stream; use React\EventLoop\Factory; use Clue\React\Term\ControlCodeParser; require __DIR__ . '/../vendor/autoload.php'; $loop = Factory::create(); if (function_exists('posix_isatty') && posix_isatty(STDIN)) { // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead) shell_exec('stty -icanon -echo'); } // process control codes from STDIN $stdin = new Stream(STDIN, $loop); $parser = new ControlCodeParser($stdin); $stdout = new Stream(STDOUT, $loop); $stdout->pause(); // pass all c0 codes through to output $parser->on('c0', array($stdout, 'write')); // replace any color codes (SGR) with a random color $parser->on('csi', function ($code) use($stdout) { // we read any color code (SGR) on the input // assign a new random foreground and background color instead if (substr($code, -1) === 'm') { $code = "[" . mt_rand(30, 37) . ';' . mt_rand(40, 47) . "m"; } $stdout->write($code); }); // reset to default color at the end $stdin->on('close', function () use($stdout) { $stdout->write("[m"); });
<?php // this example shows how the containerExport() call returns a TAR stream // and how we it can be piped into a output tar file. require __DIR__ . '/../vendor/autoload.php'; use React\EventLoop\StreamSelectLoop; use Clue\React\Docker\Factory; use React\Stream\Stream; $container = isset($argv[1]) ? $argv[1] : 'asd'; $target = isset($argv[2]) ? $argv[2] : $container . '.tar'; echo 'Exporting whole container "' . $container . '" to "' . $target . '" (pass as arguments to this example)' . PHP_EOL; $loop = new StreamSelectLoop(); $factory = new Factory($loop); $client = $factory->createClient(); $stream = $client->containerExportStream($container); $stream->on('error', function ($e = null) { // will be called if the container is invalid/does not exist echo 'ERROR requesting stream' . PHP_EOL . $e; }); $out = new Stream(fopen($target, 'w'), $loop); $out->pause(); $stream->pipe($out); $loop->run();
/** * gracefully shutdown connection by flushing all remaining data and closing stream * * @param Stream $stream */ public function endConnection(Stream $stream) { $tid = true; $loop = $this->loop; // cancel below timer in case connection is closed in time $stream->once('close', function () use(&$tid, $loop) { // close event called before the timer was set up, so everything is okay if ($tid === true) { // make sure to not start a useless timer $tid = false; } else { $loop->cancelTimer($tid); } }); // shut down connection by pausing input data, flushing outgoing buffer and then exit $stream->pause(); $stream->end(); // check if connection is not already closed if ($tid === true) { // fall back to forcefully close connection in 3 seconds if buffer can not be flushed $tid = $loop->addTimer(3.0, array($stream, 'close')); } }
<?php use Clue\React\Buzz\Browser; use React\Stream\ReadableStreamInterface; use Psr\Http\Message\ResponseInterface; use React\Stream\Stream; use RingCentral\Psr7; $url = isset($argv[1]) ? $argv[1] : 'http://google.com/'; require __DIR__ . '/../vendor/autoload.php'; $loop = React\EventLoop\Factory::create(); $client = new Browser($loop); $out = new Stream(STDOUT, $loop); $out->pause(); $info = new Stream(STDERR, $loop); $info->pause(); $info->write('Requesting ' . $url . '…' . PHP_EOL); $client->withOptions(array('streaming' => true))->get($url)->then(function (ResponseInterface $response) use($info, $out) { $info->write('Received' . PHP_EOL . Psr7\str($response)); $response->getBody()->pipe($out); }, 'printf'); $loop->run();
$container = 'asd'; //$cmd = array('echo', 'hello world'); //$cmd = array('sleep', '2'); $cmd = array('sh', '-c', 'echo -n hello && sleep 1 && echo world && sleep 1 && env'); //$cmd = array('cat', 'invalid-path'); if (isset($argv[1])) { $container = $argv[1]; $cmd = array_slice($argv, 2); } $loop = LoopFactory::create(); $factory = new Factory($loop); $client = $factory->createClient(); $out = new Stream(STDOUT, $loop); $out->pause(); $stderr = new Stream(STDERR, $loop); $stderr->pause(); // unkown exit code by default $exit = 1; $client->execCreate($container, $cmd)->then(function ($info) use($client, $out, $stderr, &$exit) { $stream = $client->execStartStream($info['Id'], false, 'stderr'); $stream->pipe($out); // forward custom stderr event to STDERR stream $stream->on('stderr', function ($data) use($stderr, $stream) { if ($stderr->write($data) === false) { $stream->pause(); $stderr->once('drain', function () use($stream) { $stream->resume(); }); } }); $stream->on('error', 'printf');
/** * @dataProvider loopProvider */ public function testDoesNotWriteDataIfClientSideHasBeenClosed($condition, $loopFactory) { if (true !== $condition()) { return $this->markTestSkipped('Loop implementation not available'); } $loop = $loopFactory(); $server = stream_socket_server('tcp://localhost:0'); $client = stream_socket_client(stream_socket_get_name($server, false)); $peer = stream_socket_accept($server); $streamA = new Stream($peer, $loop); $streamB = new Stream($client, $loop); // end streamA without writing any data $streamA->pause(); $streamA->write('hello'); $streamA->on('close', $this->expectCallableOnce()); $streamB->on('data', $this->expectCallableNever()); $streamB->close(); $loop->run(); $streamA->close(); $streamB->close(); }