Пример #1
0
 /**
  * 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);
 }
Пример #2
0
 /** @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);
 }
Пример #3
0
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();
Пример #4
0
 /**
  * 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;
     });
 }
Пример #5
0
<?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();
Пример #6
0
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();
Пример #7
0
 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();
 }
Пример #8
0
 /**
  * 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;
     });
 }
Пример #9
0
<?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);
});
Пример #10
0
 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();
 }
Пример #11
0
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();
Пример #12
0
/**
 * 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;
    }
}
Пример #13
0
 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);
     }
 }
Пример #14
0
 /**
  * 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());
     }
 }