Пример #1
0
 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];
 }
Пример #2
0
 /**
  * @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);
 }
Пример #3
0
 /**
  * @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'];
     }
 }
Пример #4
0
 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();
 }
Пример #5
0
 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);
 }
Пример #6
0
/**
 * @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;
}
Пример #7
0
 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();
 }
Пример #8
0
/**
 * 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 = [];
    }
}
Пример #9
0
 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();
     });
 }
Пример #10
0
<?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) {
Пример #11
0
 /**
  * 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);
 }
Пример #12
0
 public function __construct($fileName, $mode = "r", LoopInterface $loop = null)
 {
     $this->fileName = $fileName;
     $this->mode = $mode;
     $this->loop = $loop ?: \EventLoop\getLoop();
 }
Пример #13
0
 /**
  * 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);
 }