/** * Gets an iterator over all users in the channel. * * @return \React\Promise\PromiseInterface A promise for an array of user * objects for each member in the channel. */ public function getMembers() { $memberPromises = []; foreach ($this->data['members'] as $memberId) { $memberPromises[] = $this->client->getUserById($memberId); } return Promise\all($memberPromises); }
/** @test */ public function itShouldReceiveAgainNackedMessages() { $loop = $this->getEventLoop(); $client1 = $this->getClient($loop); $client2 = $this->getClient($loop); $counter = 0; Promise\all(array($client1->connect(1), $client2->connect(1)))->then(function () use($client1, $client2, $loop, &$counter) { $callback = function ($frame, $resolver) use($loop, &$counter) { if (0 === $counter) { $resolver->nack(); } else { $resolver->ack(); $loop->stop(); } $counter++; }; $client1->subscribeWithAck('/topic/foo', 'client-individual', $callback); $client2->subscribeWithAck('/topic/foo', 'client-individual', $callback); $client1->send('/topic/foo', 'le message à la papa'); }); $loop->run(); $this->assertEquals(2, $counter); }
use React\EventLoop\Factory; use React\Promise; $loop = Factory::create(); $myClientId = $argv[1]; // use this brutally from CLI params, it's just a demo $stdio = new Stdio($loop); (new Client($loop, ['host' => '192.168.33.99']))->connect()->then(function (Client $client) { return $client->channel(); })->then(function (Channel $channel) use($stdio, $loop, $myClientId) { // Set up I/O $stdio->getReadline()->setPrompt(sprintf('[%s] ', $myClientId)); $stdio->on('line', function ($line) use($loop, $channel, $myClientId) { if ($line === 'quit') { $loop->stop(); } $channel->publish($line, ['chatClientId' => $myClientId], 'bunny_chat_exchange'); }); return Promise\all([$channel, $channel->queueDeclare($myClientId, false, false, true, true), $channel->exchangeDeclare('bunny_chat_exchange', 'fanout'), $channel->queueBind($myClientId, 'bunny_chat_exchange')]); })->then(function (array $r) use($stdio, $myClientId) { /** @var Channel $channel */ $channel = $r[0]; return $channel->consume(function (Message $message, Channel $channel, Client $client) use($stdio, $myClientId) { $clientId = $message->getHeader('chatClientId'); // No local echo if ($clientId !== $myClientId) { $stdio->overwrite(sprintf("[%s] %s\n", $clientId, $message->content)); } $channel->ack($message); }, $myClientId); }); $loop->run();
/** * Disconnects client from server. * * Calling disconnect() multiple times or if client is not connected will result in error. * * @param int $replyCode * @param string $replyText * @return Promise\PromiseInterface */ public function disconnect($replyCode = 0, $replyText = "") { if ($this->state !== ClientStateEnum::CONNECTED) { return Promise\reject(new ClientException("Client is not connected.")); } $this->state = ClientStateEnum::DISCONNECTING; $promises = []; if ($replyCode === 0) { foreach ($this->channels as $channel) { $promises[] = $channel->close(); } } if ($this->heartbeatTimer) { $this->heartbeatTimer->cancel(); $this->heartbeatTimer = null; } return Promise\all($promises)->then(function () use($replyCode, $replyText) { return $this->connectionClose($replyCode, $replyText, 0, 0); })->then(function () { $this->eventLoop->removeReadStream($this->getStream()); $this->closeStream(); $this->init(); return $this; }); }
<?php require_once __DIR__ . '/../vendor/autoload.php'; use Bunny\Async\Client; use Bunny\Channel; use Bunny\Message; use React\EventLoop\Factory; use React\Promise; $loop = Factory::create(); (new Client($loop, ['host' => '192.168.33.99']))->connect()->then(function (Client $client) { return $client->channel(); })->then(function (Channel $channel) { return Promise\all([$channel, $channel->queueDeclare('bunny_react_queue'), $channel->exchangeDeclare('bunny_react_exchange'), $channel->queueBind('bunny_react_queue', 'bunny_react_exchange')]); })->then(function (array $r) { /** @var Channel $channel */ $channel = $r[0]; return $channel->consume(function (Message $message, Channel $channel, Client $client) { echo $message->content . "\n"; $channel->ack($message); }, 'bunny_react_queue'); }); $loop->run();
use Crunch\FastCGI\Protocol\RequestParameters; use React\Dns\Resolver\Factory as DnsResolverFactory; use React\EventLoop\Factory as EventLoopFactory; use React\SocketClient\Connector as SocketConnector; use React\Promise as promise; $loop = EventLoopFactory::create(); $dnsResolverFactory = new DnsResolverFactory(); $dns = $dnsResolverFactory->createCached('0.0.0.0', $loop); $connector = new SocketConnector($loop, $dns); $factory = new FastCGIClientFactory($loop, $connector); $factory->createClient('127.0.0.1', 1337)->then(function (Client $client) use($argv) { $name = @$argv[1] ?: 'World'; $data = "name={$name}"; $request = $client->newRequest(new RequestParameters(['REQUEST_METHOD' => 'POST', 'SCRIPT_FILENAME' => __DIR__ . '/docroot/hello-world.php', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', 'CONTENT_LENGTH' => strlen($data)]), new \Crunch\FastCGI\ReaderWriter\StringReader($data)); $request2 = $client->newRequest(new RequestParameters(['REQUEST_METHOD' => 'POST', 'SCRIPT_FILENAME' => __DIR__ . '/docroot/hello-world.php', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', 'CONTENT_LENGTH' => strlen($data)]), new \Crunch\FastCGI\ReaderWriter\StringReader($data)); $responseHandler = function ($response) use($client) { echo "\n" . $response->getContent()->read() . \PHP_EOL; }; $failHandler = function (ClientException $fail) { echo "Request failed: {$fail->getMessage()}"; return $fail; }; $x = $client->sendRequest($request)->then($responseHandler, $failHandler); $y = $client->sendRequest($request2)->then($responseHandler, $failHandler); $z = $client->sendRequest($request2)->then($responseHandler, $failHandler); $all = promise\all([$x, $y, $z]); $all->then(function () use($client) { $client->close(); }); }); $loop->run();
public function testConflictingQueueDeclareRejects() { $loop = Factory::create(); $loop->addTimer(5, function () { throw new TimeoutException(); }); $client = new Client($loop); $client->connect()->then(function (Client $client) { return $client->channel(); })->then(function (Channel $ch) { return Promise\all([$ch->queueDeclare("conflict", false, false), $ch->queueDeclare("conflict", false, true)]); })->then(function () use($loop) { $this->fail("Promise should get rejected"); $loop->stop(); }, function (\Exception $e) use($loop) { $this->assertInstanceOf("Bunny\\Exception\\ClientException", $e); $loop->stop(); }); $loop->run(); }
/** * Disconnects from AMQP server. * * @param int $replyCode * @param string $replyText * @return Promise\PromiseInterface */ public function disconnect($replyCode = 0, $replyText = "") { if ($this->state === ClientStateEnum::DISCONNECTING) { return $this->disconnectPromise; } if ($this->state !== ClientStateEnum::CONNECTED) { return Promise\reject(new ClientException("Client is not connected.")); } $this->state = ClientStateEnum::DISCONNECTING; $promises = []; if ($replyCode === 0) { foreach ($this->channels as $channel) { $promises[] = $channel->close(); } } return $this->disconnectPromise = Promise\all($promises)->then(function () use($replyCode, $replyText) { if (!empty($this->channels)) { throw new \LogicException("All channels have to be closed by now."); } $this->connectionClose($replyCode, $replyText, 0, 0); $this->closeStream(); $this->init(); return $this; }); }
<?php namespace Bunny; use Bunny\Async\Client; use React\Promise; require_once __DIR__ . "/../vendor/autoload.php"; $c = new Client(); $c->connect()->then(function (Client $c) { return $c->channel(); })->then(function (Channel $ch) { return Promise\all([$ch, $ch->queueDeclare("bench_queue"), $ch->exchangeDeclare("bench_exchange"), $ch->queueBind("bench_queue", "bench_exchange")]); })->then(function ($r) { /** @var Channel $ch */ $ch = $r[0]; $t = null; $count = 0; return $ch->consume(function (Message $msg, Channel $ch, Client $c) use(&$t, &$count) { if ($t === null) { $t = microtime(true); } if ($msg->content === "quit") { printf("Pid: %s, Count: %s, Time: %.4f\n", getmypid(), $count, microtime(true) - $t); $c->disconnect()->then(function () use($c) { $c->stop(); }); } else { ++$count; } }, "bench_queue", "", false, true); });
public function testGet() { $loop = Factory::create(); $loop->addTimer(1, function () { throw new TimeoutException(); }); $client = new Client($loop); /** @var Channel $channel */ $channel = null; $client->connect()->then(function (Client $client) { return $client->channel(); })->then(function (Channel $ch) use(&$channel) { $channel = $ch; return Promise\all([$channel->queueDeclare("get_test"), $channel->publish(".", [], "", "get_test")]); })->then(function () use(&$channel) { return $channel->get("get_test", true); })->then(function (Message $message1 = null) use(&$channel) { $this->assertNotNull($message1); $this->assertInstanceOf("Bunny\\Message", $message1); $this->assertEquals($message1->exchange, ""); $this->assertEquals($message1->content, "."); return $channel->get("get_test", true); })->then(function (Message $message2 = null) use(&$channel) { $this->assertNull($message2); return $channel->publish("..", [], "", "get_test"); })->then(function () use(&$channel) { return $channel->get("get_test"); })->then(function (Message $message3 = null) use(&$channel) { $this->assertNotNull($message3); $this->assertInstanceOf("Bunny\\Message", $message3); $this->assertEquals($message3->exchange, ""); $this->assertEquals($message3->content, ".."); $channel->ack($message3); return $channel->getClient()->disconnect(); })->then(function () use($loop) { $loop->stop(); }); $loop->run(); }
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyza EOT; $time = microtime(true); $max = isset($argv[1]) ? (int) $argv[1] : 1; $c->connect()->then(function (Client $c) { return $c->channel(); })->then(function (Channel $ch) { return Promise\all([$ch, $ch->queueDeclare("bench_queue"), $ch->exchangeDeclare("bench_exchange"), $ch->queueBind("bench_queue", "bench_exchange")]); })->then(function ($r) use($body, &$time, &$max) { /** @var Channel $ch */ $ch = $r[0]; $promises = []; for ($i = 0; $i < $max; $i++) { $promises[] = $ch->publish($body, [], "bench_exchange"); } $promises[] = $ch->publish("quit", [], "bench_exchange"); return Promise\all($promises); })->then(function () use($c) { return $c->disconnect(); })->then(function () use($c, &$time) { echo microtime(true) - $time, "\n"; $c->stop(); }); $c->run();
/** * wait for ALL of the given promises to resolve * * Once the last promise resolves, this will return an array with whatever * each promise resolves to. Array keys will be left intact, i.e. they can * be used to correlate the return array to the promises passed. * * If ANY promise fails to resolve, this will try to cancel() all * remaining promises and throw an Exception. * * If no $timeout is given and either promise stays pending, then this will * potentially wait/block forever until the last promise is settled. * * If a $timeout is given and either promise is still pending once the timeout * triggers, this will cancel() all pending promises and throw a `TimeoutException`. * * @param array $promises * @param LoopInterface $loop * @param null|float $timeout (optional) maximum timeout in seconds or null=wait forever * @return array returns an array with whatever each promise resolves to * @throws Exception when ANY promise is rejected * @throws TimeoutException if the $timeout is given and triggers */ function awaitAll(array $promises, LoopInterface $loop, $timeout = null) { try { return await(Promise\all($promises), $loop, $timeout); } catch (Exception $e) { // ANY of the given promises rejected or the timeout fired // => try to cancel all promises (rejected ones will be ignored anyway) _cancelAllPromises($promises); throw $e; } }
protected function execute(InputInterface $input, OutputInterface $output) { $loop = Factory::create(); $nope = function (\Exception $e) use($output) { $output->writeln("<bg=red>{$e->getMessage()}</>"); }; $c = new Client($loop, ['host' => $input->getOption('host'), 'port' => (int) $input->getOption('port'), 'user' => $input->getOption('user'), 'pass' => $input->getOption('pass'), 'vhost' => $input->getOption('vhost')]); $conn = $c->connect(); $conn->then(function () use($output) { $output->writeln('<bg=green>Connected...</>'); }); if (null !== ($destination = $input->getOption('pipe'))) { $conn->then(function (Client $c) { return $c->channel(); })->then(function (Channel $ch) use($loop, $destination, $input) { $stdin = new Stream(fopen('php://stdin', 'r+'), $loop); $bindings = new Bindings($destination); $dataParser = function ($data) use($input) { return '' !== $input->getOption('delimiter') ? explode($input->getOption('delimiter'), trim($data)) : [trim($data)]; }; $once = $input->getOption('once') ? function () use($ch) { $ch->close()->then(function () use($ch) { $ch->getClient()->disconnect(); }); } : function () { }; $stdin->on('data', function ($data) use($ch, $bindings, $dataParser, $once) { Promise\all(array_map(function ($message) use($ch, $bindings) { return $ch->publish($message, [], $bindings->exchange, $bindings->routingKey); }, array_filter($dataParser($data), function ($message) { return '' !== $message; })))->then($once); }); }, $nope); if ($this->defaultBinding === $input->getOption('bind')) { $input->setOption('bind', []); } } $consume = function (Message $msg) use($input, $output) { $this->consume($msg, $input, $output); }; if ([] !== $input->getOption('consume')) { $conn->then(function (Client $c) { return $c->channel(); })->then(function (Channel $ch) use($input, $consume) { return Promise\all(array_map(function ($queue) use($ch, $consume) { return $ch->consume($consume, $queue, '', false, true, true); }, $input->getOption('consume'))); }, $nope); if ($this->defaultBinding === $input->getOption('bind')) { $input->setOption('bind', []); } } if ([] !== $input->getOption('bind')) { $conn->then(function (Client $c) { return $c->channel(); })->then(function (Channel $ch) { return Promise\all([$ch, $ch->queueDeclare('', false, false, true, true)]); })->then(function ($r) use($input) { list($ch, $qr) = $r; return Promise\all(array_merge([$ch, $qr], array_map(function ($exKey) use($ch, $qr) { $bindings = new Bindings($exKey); return $ch->queueBind($qr->queue, $bindings->exchange, $bindings->routingKey, false, $bindings->headers); }, $input->getOption('bind')))); })->then(function ($r) use($consume) { return $r[0]->consume($consume, $r[1]->queue, '', false, true, true); }, $nope); } try { $c->run(); } catch (\Exception $e) { $nope($e); } }
/** * Implement's module logic for given hook * * @param \AppserverIo\Psr\HttpMessage\RequestInterface $request A request object * @param \AppserverIo\Psr\HttpMessage\ResponseInterface $response A response object * @param \AppserverIo\Server\Interfaces\RequestContextInterface $requestContext A requests context instance * @param int $hook The current hook to process logic for * * @return bool * @throws \AppserverIo\Server\Exceptions\ModuleException */ public function process(RequestInterface $request, ResponseInterface $response, RequestContextInterface $requestContext, $hook) { try { // in php an interface is, by definition, a fixed contract. It is immutable. // so we have to declair the right ones afterwards... /** * @var $request \AppserverIo\Psr\HttpMessage\RequestInterface */ /** * @var $request \AppserverIo\Psr\HttpMessage\ResponseInterface */ // if false hook is coming do nothing if (ModuleHooks::REQUEST_POST !== $hook) { return; } // check if server handler sais php modules should react on this request as file handler if ($requestContext->getServerVar(ServerVars::SERVER_HANDLER) !== self::MODULE_NAME) { return; } // check if file does not exist if ($requestContext->hasServerVar(ServerVars::SCRIPT_FILENAME) === false) { $response->setStatusCode(404); throw new ModuleException(null, 404); } // initialize the event loop $loop = EventLoopFactory::create(); // invoke the FastCGI request $this->getFastCgiClient($requestContext, $loop)->done(function (Client $client) use($request, $requestContext, $response) { // initialize the environment $env = $this->prepareEnvironment($request, $requestContext); // initialize the request $req = $client->newRequest(new RequestParameters($env), new \Crunch\FastCGI\ReaderWriter\StringReader($request->getBodyContent())); // initialize the response handler $responseHandler = function ($res) use($response) { // explode status code, headers and body from the FastCGI response list($statusCode, $headers, $body) = $this->formatResponse($res->getContent()->read()); // set the headers found in the Fast-CGI response foreach ($headers as $headerName => $headerValue) { // if found an array, e. g. for the Set-Cookie header, we add each value if (is_array($headerValue)) { foreach ($headerValue as $value) { $response->addHeader($headerName, $value, true); } } else { $response->addHeader($headerName, $headerValue); } } // initialize the HTTP response with the values $response->appendBodyStream($body); $response->setStatusCode($statusCode); }; // finally send the FastCGI request $x = $client->sendRequest($req)->then($responseHandler); // close the FastCGI connection promise\all([$x])->then(function () use($client) { $client->close(); }); }); // start the event loop $loop->run(); // append the X-Powered-By header $response->addHeader(Protocol::HEADER_X_POWERED_BY, __CLASS__, true); // set response state to be dispatched after this without calling other modules process $response->setState(HttpResponseStates::DISPATCH); } catch (\Exception $e) { // catch all exceptions throw new ModuleException($e->getMessage(), $e->getCode()); } }