private function runTestWith($method, $url, array $headers = [], $protocolVersion = '1.0', $body) { $router = $this->createTestRouter(); $wampPost = new WampPost("test_realm", \EventLoop\getLoop(), "127.0.0.1", 18181); $opened = false; $wampPost->on('open', function (ClientSession $session) use(&$opened, $router) { $opened = true; $session->register("procedure.that.errors", function () { throw new WampErrorException("my.custom.error", [4, 5, 6], (object) ["x" => "y"], (object) ["y" => "z"]); }); $this->_testTopicEvents = []; // this subscription is here to test that options are working ("exclude_me") $session->subscribe("wamppost.tests.nonexclude.topic", function ($args, $argsKw, $details, $pubId) { $event = new EventMessage(0, $pubId, $details, $args, $argsKw, "wamppost.tests.nonexclude.topic"); $this->_testTopicEvents[] = $event; }); }); $router->addInternalClient($wampPost); $response = null; $responseBody = null; \EventLoop\addTimer(0, function () use(&$response, &$responseBody, $method, $url, $headers, $protocolVersion, $body) { $this->makeHttpRequest($method, $url, $headers, $protocolVersion, $body)->then(function ($ret) use(&$response, &$responseBody) { list($response, $responseBody) = $ret; $this->stopRouter(); }); }); $this->startRouterWithTimeout(5); $this->assertEmpty($this->expectedMessages); $this->assertNotNull($response); $this->assertNotNull($responseBody); $this->assertTrue($opened); return [$response, $responseBody, $this->recordedEvents]; }
/** * @test */ public function fromFile_exceed_buffer() { //Create a 10k temp file $temp = tmpfile(); fwrite($temp, str_repeat("1", 10000)); $meta_data = stream_get_meta_data($temp); $filename = $meta_data["uri"]; /** @var LoopInterface $loop */ $loop = \EventLoop\getLoop(); $source = new FromFileObservable($filename); $result = false; $complete = false; $error = false; $source->subscribe(new CallbackObserver(function ($value) use(&$result) { $result = $value; }, function ($e) use(&$error) { $error = true; }, function () use(&$complete) { $complete = true; })); $loop->tick(); $this->assertEquals("4096", strlen($result)); $this->assertFalse($complete); $this->assertFalse($error); $loop->tick(); $this->assertEquals("4096", strlen($result)); $this->assertFalse($complete); $this->assertFalse($error); $loop->tick(); $this->assertEquals("1808", strlen($result)); $this->assertTrue($complete); $this->assertFalse($error); }
/** * @param $parameters * @param \React\EventLoop\LoopInterface $loop */ public function __construct($parameters, LoopInterface $loop = null) { $this->parameters = $parameters; $this->loop = $loop ?: \EventLoop\getLoop(); if (isset($parameters['auto_disconnect'])) { $this->autoDisconnect = $parameters['auto_disconnect']; } }
private function startConnection() { $loop = \EventLoop\getLoop(); $dnsResolverFactory = new Factory(); $dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $loop); $factory = new \React\HttpClient\Factory(); $client = $factory->create($loop, $dnsResolver); $cNegotiator = new ClientNegotiator($this->url, $this->subProtocols); $headers = $cNegotiator->getRequest()->getHeaders(); $flatHeaders = []; foreach ($headers as $k => $v) { $flatHeaders[$k] = $v[0]; } $request = $client->request("GET", $this->url, $flatHeaders, '1.1'); $request->on('response', function (Response $response, Request $request) use($cNegotiator) { if ($response->getCode() !== 101) { throw new \Exception("Unexpected response code " . $response->getCode()); } // TODO: Should validate response //$cNegotiator->validateResponse($response); $subprotoHeader = ""; $psr7Response = new \GuzzleHttp\Psr7\Response($response->getCode(), $response->getHeaders(), null, $response->getVersion()); if (count($psr7Response->getHeader('Sec-WebSocket-Protocol')) == 1) { $subprotoHeader = $psr7Response->getHeader('Sec-WebSocket-Protocol')[0]; } parent::onNext(new MessageSubject(new AnonymousObservable(function (ObserverInterface $observer) use($response) { $response->on('data', function ($data) use($observer) { $observer->onNext($data); }); $response->on('error', function ($e) use($observer) { $observer->onError($e); }); $response->on('close', function () use($observer) { $observer->onCompleted(); }); $response->on('end', function () use($observer) { $observer->onCompleted(); // complete the parent observer - we only do 1 connection parent::onCompleted(); }); return new CallbackDisposable(function () use($response) { // commented this out because disposal was causing the other // end (the request) to close also - which causes the pending messages // to get tossed //$response->close(); }); }), new CallbackObserver(function ($x) use($request) { $request->write($x); }, function ($e) use($request) { $request->close(); }, function () use($request) { $request->end(); }), true, $this->useMessageObject, $subprotoHeader, $cNegotiator->getRequest(), $psr7Response)); }); $request->writeHead(); }
public function __construct($method, $url, $body = null, array $headers = [], $protocolVersion = '1.0', $bufferResults = true, $includeResponse = false) { $this->method = $method; $this->url = $url; $this->body = $body; $this->headers = $headers; $this->protocolVersion = $protocolVersion; $this->bufferResults = $bufferResults; $this->includeResponse = $includeResponse; $loop = \EventLoop\getLoop(); $dnsResolverFactory = new Factory(); $dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $loop); $factory = new \React\HttpClient\Factory(); $this->client = $factory->create($loop, $dnsResolver); }
/** * @param Observable $observable * @param LoopInterface|null $loop * @return null * @throws \Exception */ function awaitOnce(Observable $observable, LoopInterface $loop = null) { $loop = $loop ?: \EventLoop\getLoop(); $done = false; $res = null; $observable->subscribeCallback(function ($el) use(&$done, &$res) { $res = $el; $done = true; }, function ($e) use(&$done, &$res) { $res = $e; $done = true; }, function () use(&$done) { $done = true; }, new EventLoopScheduler($loop)); while (!$done) { $loop->tick(); } if ($res instanceof \Exception) { throw $res; } return $res; }
protected function makeHttpRequest($method, $url, array $headers = [], $protocolVersion = '1.0', $body) { $dnsResolverFactory = new Factory(); $dnsResolver = $dnsResolverFactory->createCached("127.0.0.1", \EventLoop\getLoop()); $httpFactory = new \React\HttpClient\Factory(); $httpClient = $httpFactory->create(\EventLoop\getLoop(), $dnsResolver); $deferred = new Deferred(); $request = $httpClient->request($method, $url, $headers, $protocolVersion); $request->writeHead(); $request->write($body); $request->on('response', function ($response) use($deferred) { $responseBody = ""; $response->on('data', function ($data, $response) use(&$responseBody) { $responseBody .= $data; }); $response->on('end', function () use(&$responseBody, $deferred, $response) { $deferred->resolve([$response, $responseBody]); }); }); $request->end(); return $deferred->promise(); }
/** * Wait until observable completes. * * @param Observable|ObservableInterface $observable * @param LoopInterface $loop * @return \Generator */ function await(Observable $observable, LoopInterface $loop = null) { $completed = false; $results = []; $loop = $loop ?: \EventLoop\getLoop(); $scheduler = new EventLoopScheduler($loop); $observable->subscribe(new CallbackObserver(function ($value) use(&$results, &$results, $loop) { $results[] = $value; $loop->stop(); }, function ($e) use(&$completed) { $completed = true; throw $e; }, function () use(&$completed) { $completed = true; }), $scheduler); while (!$completed) { $loop->run(); foreach ($results as $result) { (yield $result); } $results = []; } }
public function subscribe(ObserverInterface $observer, $scheduler = null) { $socket = new \React\Socket\Server(\EventLoop\getLoop()); $negotiator = new Negotiator(new Validator()); if (!empty($this->subProtocols)) { $negotiator->setSupportedSubProtocols($this->subProtocols); } $http = new \React\Http\Server($socket); $http->on('request', function (Request $request, Response $response) use($negotiator, $observer, &$outStream) { $uri = new Uri($request->getPath()); if (count($request->getQuery()) > 0) { $uri = $uri->withQuery(\GuzzleHttp\Psr7\build_query($request->getQuery())); } $psrRequest = new \GuzzleHttp\Psr7\Request($request->getMethod(), $uri, $request->getHeaders()); // cram the remote address into the header in out own X- header so // the user will have access to it $psrRequest = $psrRequest->withAddedHeader("X-RxWebsocket-Remote-Address", $request->remoteAddress); $negotiatorResponse = $negotiator->handshake($psrRequest); $response->writeHead($negotiatorResponse->getStatusCode(), array_merge($negotiatorResponse->getHeaders(), ["Content-Length" => "0"])); if ($negotiatorResponse->getStatusCode() !== 101) { $response->end(); return; } $subProtocol = ""; if (count($negotiatorResponse->getHeader('Sec-WebSocket-Protocol')) > 0) { $subProtocol = $negotiatorResponse->getHeader('Sec-WebSocket-Protocol')[0]; } $connection = new MessageSubject(new AnonymousObservable(function (ObserverInterface $observer) use($request) { $request->on('data', function ($data) use($observer) { $observer->onNext($data); }); $request->on('error', function ($error) use($observer) { $observer->onError($error); }); $request->on('close', function () use($observer) { $observer->onCompleted(); }); $request->on('end', function () use($observer) { $observer->onCompleted(); }); return new CallbackDisposable(function () use($request) { $request->close(); }); }), new CallbackObserver(function ($x) use($response) { $response->write($x); }, function ($error) use($response) { $response->close(); }, function () use($response) { $response->end(); }), false, $this->useMessageObject, $subProtocol, $psrRequest, $negotiatorResponse); $observer->onNext($connection); }); $socket->listen($this->port, $this->bindAddress); // $http->on('end', function () {}); // $http->on('data', function () {}); // $http->on('pause', function () {}); // $http->on('resume', function () {}); $this->started = true; return new CallbackDisposable(function () use($socket) { $socket->shutdown(); }); }
<?php require_once __DIR__ . '/../bootstrap.php'; const AGENT = "Websocket/0.0.0"; echo "Using " . get_class(\EventLoop\getLoop()) . "\n"; $runReports = function () { echo "Generating report.\n"; $reportUrl = "ws://127.0.0.1:9001/updateReports?agent=" . AGENT . "&shutdownOnComplete=true"; $client = new \Rx\Websocket\Client($reportUrl); $client->subscribe(new \Rx\Observer\CallbackObserver()); }; $runIndividualTest = function ($case) { echo "Running " . $case . "\n"; $casePath = "/runCase?case={$case}&agent=" . AGENT; $client = new \Rx\Websocket\Client("ws://127.0.0.1:9001" . $casePath, true); $deferred = new \React\Promise\Deferred(); $client->subscribe(new \Rx\Observer\CallbackObserver(function (\Rx\Websocket\MessageSubject $messages) { $messages->subscribe(new \Rx\Observer\CallbackObserver(function ($x) use($messages) { //echo $x . "\n"; $messages->onNext($x); }, [$messages, "onError"], [$messages, "onCompleted"])); }, function ($error) use($case, $deferred) { echo "Error on " . $case . "\n"; $deferred->reject($error); }, function () use($case, $deferred) { echo "Finished " . $case . "\n"; $deferred->resolve(); })); return $deferred->promise(); }; $runTests = function ($testCount) use($runIndividualTest, $runReports) {
/** * StreamSubject constructor. * * @param resource $resource * @param LoopInterface|null $loop */ public function __construct($resource, LoopInterface $loop = null) { $loop = $loop ?: \EventLoop\getLoop(); $this->stream = new Stream($resource, $loop); }
public function __construct($fileName, $mode = "r", LoopInterface $loop = null) { $this->fileName = $fileName; $this->mode = $mode; $this->loop = $loop ?: \EventLoop\getLoop(); }
/** * ToFileObserver constructor. * * @param string $fileName * @param LoopInterface|null $loop */ public function __construct($fileName, LoopInterface $loop = null) { $loop = $loop ?: \EventLoop\getLoop(); parent::__construct(fopen($fileName, 'w'), $loop); }