public function provideListeners(ListenerAcceptorInterface $acceptor)
 {
     $acceptor->addListener('ip', function ($event, $ip) {
         $this->client->get('https://freegeoip.net/json/' . $ip, ['future' => true])->then(function (Response $response) {
             $this->emitter->emit('sse', ['type' => 'geo', 'payload' => $response->json()['region_name']]);
         });
     });
 }
 public function provideListeners(ListenerAcceptorInterface $acceptor)
 {
     $acceptor->addListener('lookup', function ($event, $hostname) {
         $this->resolver->resolve($hostname)->then(function ($ip) {
             $this->emitter->emit('ip', $ip);
             $this->emitter->emit('sse', ['type' => 'dns', 'payload' => $ip]);
         });
     });
 }
 public function provideListeners(ListenerAcceptorInterface $acceptor)
 {
     $acceptor->addListener('lookup', function ($event, $hostname) {
         $this->client->get('http://' . $hostname . '/', ['future' => true])->then(function (Response $response) {
             if (preg_match('/<title>(.+)<\\/title>/', $response->getBody()->getContents(), $matches) && isset($matches[1])) {
                 $title = $matches[1];
                 $this->emitter->emit('sse', ['type' => 'title', 'payload' => $title]);
             }
         });
     });
 }
예제 #4
0
 /**
  * @param EventInterface|string $event
  * @throws \InvalidArgumentException
  * @return bool true if emitted, false otherwise
  */
 private function emitEvent($event)
 {
     if (is_null($this->eventEmitter)) {
         return false;
     }
     if (!is_string($event) && !$event instanceof EventInterface) {
         throw new \InvalidArgumentException('Event must be either be of type "string" or instance of League\\Event\\EventInterface');
     }
     $this->eventEmitter->emit($event);
     return true;
 }
 public function testDecoratingRenderedOutputInAfterRenderEvent()
 {
     $mock = $this->getMockRenderer('foobar');
     $dispatcher = new Emitter();
     $dispatcher->addListener(EventTriggeringRenderer::AFTER_RENDER_EVENT, function ($event) {
         $event->setOutput($event->getOutput() . ' + called from event');
     });
     $renderer = new EventTriggeringRenderer($mock, $dispatcher);
     $text = $renderer->render('some source');
     $this->assertSame('foobar + called from event', $text);
 }
예제 #6
0
 public function testResponseReady()
 {
     $emitter = new Emitter();
     $callback = function ($event, $parms) {
         $this->assertInstanceOf(Response::class, $parms['response']);
     };
     $emitter->addListener('response_ready', CallbackListener::fromCallable($callback));
     $api = new Server($emitter);
     $api->registerServiceLoader(new DirectoryServiceLoader(__DIR__ . '/services', '\\TestApi'));
     $request = Request::create('/v1/test/123', 'GET');
     $response = $api->run($request);
 }
 public function register(ContainerInterface $container)
 {
     $config = $this->getConfig();
     $container['events'] = function () use($config) {
         $emitter = new Emitter();
         foreach ($config['listeners'] as $event => $eventListeners) {
             foreach ($eventListeners as $eventListener) {
                 $emitter->addListener($event, $eventListener);
             }
         }
         return $emitter;
     };
 }
예제 #8
0
 /**
  * Register Event Listeners.
  *
  * @param 	array $appEvents
  * @return	void
  */
 protected function loadEvents($appEvents)
 {
     foreach ((array) $appEvents as $appEventType => $events) {
         foreach ($events as $event) {
             $this->eventDispatcher->addListener($appEventType, $this->container->get($event));
         }
     }
 }
 /**
  * Create event emitter and set optional events as array or \League\Event\ListenerProviderInterface.
  * Set as second argument a emitter instance, otherwise the factory creates a new one.
  *
  * Event array could have a name-handler-pair, a listener provider as instance of
  * `\League\Event\ListenerProviderInterface` or a argument array with name, handler and priority
  *
  * Configure event array as follows:
  *
  * ```
  * $events = [
  *      // name-handler-pair
  *      'eventName' => function(){},
  *
  *      // listener provider as instance of \League\Event\ListenerProviderInterface
  *      new \Acme\MyListenerProvider
  *
  *      // argument array name, handler, prio
  *      ['name', function(){}, 10]
  *
  *      // alternating argument array name => [handler, prio]
  *      'eventName' => [function(){}, 10]
  *
  * ];
  * ```
  *
  * @param \League\Event\ListenerProviderInterface|array $events
  * @param \League\Event\EmitterInterface $emitter
  *
  * @return Emitter
  */
 public function createEventEmitter($events = [], EmitterInterface $emitter = null)
 {
     if (null === $emitter) {
         $emitter = new Emitter();
     }
     if (!is_array($events)) {
         $events = [$events];
     }
     if (!empty($events)) {
         foreach ($events as $name => $handler) {
             if ($handler instanceof ListenerProviderInterface) {
                 $emitter->useListenerProvider($handler);
                 continue;
             }
             $args = is_array($handler) ? array_merge([$name], $handler) : [$name, $handler, EmitterInterface::P_NORMAL];
             call_user_func_array([$emitter, 'addListener'], $args);
         }
     }
     return $emitter;
 }
예제 #10
0
 /**
  * Emits the events corresponding to applying the provided input on the provided object.
  *
  * @param Input $input
  * @param Stateful $object
  * @param Context $context
  * @param State $nextState
  *
  * @return void
  *
  * @throws StateTransitionFailed
  */
 private function emitEvents(Input $input, Stateful $object, Context $context, State $nextState)
 {
     /** @var Event $event */
     foreach ($this->eventProvider($input, $object->getCurrentState()) as $event) {
         if (!$this->emitter->hasListeners($event->getName())) {
             continue;
         }
         if ($this->emitter->emit($event, $object, $context, $input, $nextState)->isPropagationStopped()) {
             $this->emitter->emit(Event::named('failed'), $object, $context, $input, $nextState);
             throw new StateTransitionFailed($input, $object, $context, $nextState);
         }
     }
 }
예제 #11
0
 public function it_can_add_a_converter(ConverterInterface $converter, Emitter $emitter)
 {
     $pHigh = EmitterInterface::P_HIGH;
     $pNormal = EmitterInterface::P_NORMAL;
     $pLow = EmitterInterface::P_LOW;
     $converter->getSubscribedEvents()->shouldBeCalled()->willReturn(['img' => 'handleImg', 'convert.foo' => ['handleFoo', $pHigh], 'convert.bar' => ['handleBar', $pLow], 'convertfizz' => ['badFizzHandler'], 'convert..buzz' => ['badBuzzHandler']]);
     $emitter->addListener('convert.img', [$converter, 'handleImg'], $pNormal)->shouldBeCalled();
     $emitter->addListener('convert.foo', [$converter, 'handleFoo'], $pHigh)->shouldBeCalled();
     $emitter->addListener('convert.bar', [$converter, 'handleBar'], $pLow)->shouldBeCalled();
     $emitter->addListener('convert.convertfizz', [$converter, 'badFizzHandler'], $pNormal)->shouldBeCalled();
     $emitter->addListener('convert..buzz', [$converter, 'badBuzzHandler'], $pNormal)->shouldBeCalled();
     $this->addConverter($converter)->shouldReturn($this);
 }
예제 #12
0
 /**
  * A client is attempting to publish content to a subscribed connections on a URI
  *
  * @param \Ratchet\ConnectionInterface $conn
  * @param string|Topic $topic The topic the user has attempted to publish to
  * @param string $event Payload of the publish
  * @param array $exclude A list of session IDs the message should be excluded from (blacklist)
  * @param array $eligible A list of session Ids the message should be send to (whitelist)
  */
 function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible)
 {
     switch ((string) $topic) {
         case self::BUZZER_TOPIC:
             $contestant = new Contestant($event['name']);
             $this->emitter->emit(new BuzzReceivedEvent($contestant, $event['difference']));
             break;
         case self::BUZZER_STATUS_TOPIC:
             $this->emitter->emit(new BuzzerStatusChangeEvent(new BuzzerStatus($event['active'])));
             break;
         case self::CONTESTANT_SCORE:
             if (!isset($event['diff']) || !isset($event['contestant'])) {
                 // TODO logging
                 echo "Invalid parameters sent to update contestant score\n";
                 print_r($event);
                 break;
             }
             $this->emitter->emit(new ContestantScoreChangeEvent($event['contestant'], $event['diff']));
             break;
         case self::QUESTION_DISPLAY_TOPIC:
             if (!isset($event['category']) || !isset($event['value'])) {
                 //TODO log this
                 echo "Did not receive proper question request, did not have a category or value\n";
                 break;
             }
             $this->emitter->emit(new QuestionDisplayRequestEvent($event['category'], $event['value']));
             break;
         case self::QUESTION_ANSWER_QUESTION:
             if (!isset($event['category']) || !isset($event['value']) || !isset($event['contestant'])) {
                 //TODO log this
                 echo "Did not receive proper question answer request, did not have a category or value or playerName\n";
                 break;
             }
             $questionAnswerEvent = new Question\QuestionAnswerEvent(new Question\QuestionAnswer($event['category'], $event['value'], new Contestant($event['contestant']), isset($event['correct']) ? $event['correct'] : false));
             if (isset($event['bet'])) {
                 $questionAnswerEvent->getQuestionAnswer()->setBet($event['bet']);
             }
             $this->emitter->emit($questionAnswerEvent);
             break;
         case self::QUESTION_DISMISS_TOPIC:
             if (!isset($event['category']) || !isset($event['value'])) {
                 //TODO log this
                 echo "Did not receive proper dismiss request, did not have a category or value\n";
                 break;
             }
             $dismissal = new Question\QuestionDismissalEvent(new Question\QuestionDismissal($event['category'], $event['value']));
             $this->emitter->emit($dismissal);
             break;
         case self::DAILY_DOUBLE_BET_TOPIC:
             if (!isset($event['category']) || !isset($event['value']) || !isset($event['bet'])) {
                 //TODO logging
                 echo "Recieved invalid daily double bet\n";
                 break;
             }
             $this->emitter->emit(new Question\DailyDouble\DailyDoubleBetEvent($event['value'], $event['category'], $event['bet']));
             break;
         case self::FINAL_JEOPARDY_TOPIC:
             if (!isset($event['content'])) {
                 //TODO logging
                 echo "Recieved invalid final jeopardy topic request - no content selection";
                 break;
             }
             if ($event['content'] == "category") {
                 $this->emitter->emit(new Question\FinalJeopardy\FinalJeopardyCategoryRequest());
                 break;
             }
             if ($event['content'] == "clue") {
                 echo "Recieved clue request";
                 $this->emitter->emit(new Question\FinalJeopardy\FinalJeopardyClueRequest());
                 break;
             }
             if ($event['content'] == "answer") {
                 $this->emitter->emit(new Question\FinalJeopardy\FinalJeopardyAnswerRequest());
                 break;
             }
             break;
         case self::FINAL_JEOPARDY_RESPONSES_TOPIC:
             if (!isset($event['contestant']) || !isset($event['type'])) {
                 //TODO logging
                 echo "Invalid jeopardy response, did not specify type or did not include contestant\n";
                 print_r($event);
                 break;
             }
             if ($event['type'] == "bet") {
                 if (!isset($event['bet'])) {
                     //TODO logging
                     echo "Invalid final jeopardy bet, did not include a bet value\n";
                     print_r($event);
                     break;
                 }
                 $this->emitter->emit(new Question\FinalJeopardy\FinalJeopardyBetEvent($event['contestant'], $event['bet']));
                 break;
             }
             if ($event['type'] == "answer") {
                 if (!isset($event['answer'])) {
                     //TODO Logging
                     echo "Invalid final jeopardy answer, did not include an answer response\n";
                     print_r($event);
                     break;
                 }
                 $this->emitter->emit(new Question\FinalJeopardy\FinalJeopardyAnswerEvent($event['contestant'], $event['answer']));
                 break;
             }
             break;
         case self::FINAL_JEOPARDY_ANSWER_TOPIC:
             //TODO error checking
             $this->emitter->emit(new Question\FinalJeopardy\FinalJeopardyResponseRequest($event['contestant']));
             break;
         default:
             break;
     }
 }
예제 #13
0
 /**
  * Add a listener
  *
  * @param string event name
  * @param mixed listener a closure or FQCN
  * @param int priority, default = 0
  * @return void
  */
 public function listen($name, $listener, $priority = EmitterInterface::P_NORMAL)
 {
     self::$emitter->addListener($name, $listener, $priority);
 }
예제 #14
0
 /**
  * @dataProvider eventEmitterProxyData
  */
 public function testEventEmitArguments($engineMethod, $eventType)
 {
     $emitter = new Emitter();
     $actual = null;
     $emitter->addListener($eventType, function (...$args) use(&$actual) {
         array_shift($args);
         // we expect the first argument to be an event
         $actual = $args;
     });
     $engine = new ExtraEventEmitArgs($this->mockPluginManager, $emitter);
     if ($eventType === Engine::EXCEPTION_THROWN_EVENT) {
         $engine->onAppExecute(function () {
             throw new \Exception();
         });
     }
     $engine->run();
     $this->assertSame([$engine, 1, 'foo', 'bar'], $actual);
 }
예제 #15
0
 /**
  * Add an event listener to the event emitter
  *
  * @param string   $eventName Event name
  * @param callable $listener  Callable function or method
  */
 public function addEventListener($eventName, callable $listener)
 {
     $this->eventEmitter->addListener($eventName, $listener);
 }
예제 #16
0
 /**
  * Add an event listener to the event emitter
  *
  * @param string   $eventName Event name
  * @param callable $listener  Callable function or method
  * @param int      $priority  Priority of event listener
  */
 public function addEventListener($eventName, callable $listener, $priority = Emitter::P_NORMAL)
 {
     $this->eventEmitter->addListener($eventName, $listener, $priority);
 }
 /**
  * Inform ContentEvent of our ModifyContentListener in order to transform the content body attribute
  * from Markdown to HTML.
  *
  * @param \League\Event\Emitter $event
  */
 protected function registerEventListeners(Emitter $event)
 {
     $event->addListener('ContentEvent', new ContentListener());
 }
 /**
  * @inheritDoc
  */
 public function handle(DomainMessage $domainMessage)
 {
     $this->emitter->emit($domainMessage->getPayload());
 }
예제 #19
0
파일: index.php 프로젝트: sforsman/rest
require __DIR__ . '/vendor/autoload.php';
// Include our simple REST Service
require 'PageService.php';
use sforsman\Rest\Server;
use sforsman\Rest\AbstractJsonService;
use League\Event\Emitter;
use League\Event\AbstractEvent;
use League\Event\CallbackListener;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// Setup a logger
$log = new Logger('API');
$log->pushHandler(new StreamHandler('/tmp/api_log.txt', Logger::WARNING));
// We are interested in some events generated by the server
$emitter = new Emitter();
// This will be emitted right before control is dispatched to the actual service
$callback = function (AbstractEvent $event, $param = null) use($log) {
    // In the real world, you would (for an example) validate OAuth2 headers here
    $log->addNotice(serialize($param));
};
$emitter->addListener('dispatch', CallbackListener::fromCallable($callback));
// This will be emitted when an exception is going to be processed and "converted" into JSON
$callback = function ($event, $param) use($log) {
    $log->addError($param['exception']->getMessage());
};
$emitter->addListener('exception', CallbackListener::fromCallable($callback));
// This will be emitted when an PHP error (warning, notice, fatal) has happened and the processing
$callback = function ($event, $errorStr) use($log) {
    $log->addWarning($errorStr);
};
예제 #20
0
 /**
  * The thread's run() method that runs asynchronously.
  *
  * @link http://www.php.net/manual/en/thread.run.php
  */
 public function run()
 {
     // register a shutdown handler for controlled shutdown
     register_shutdown_function(array(&$this, 'shutdown'));
     // we need the autloader again
     require SERVER_AUTOLOADER;
     // create the service emitter
     $emitter = new Emitter();
     // load the bootstrap configuration
     /** @var \AppserverIo\Appserver\Core\Api\Node\BootstrapNodeInterface $bootstrapNode */
     $bootstrapNode = $this->doLoadBootstrap($this->getBootstrapConfigurationFilename());
     // iterate over the listeners and add them to the emitter
     /** @var \AppserverIo\Appserver\Core\Api\Node\ListenerNodeInterface $listener */
     foreach ($bootstrapNode->getListeners() as $listener) {
         // load the listener class name
         $listenerClassName = $listener->getType();
         // create a new instance of the listener class
         /** @var \League\Event\ListenerInterface $listenerInstance */
         $listenerInstance = new $listenerClassName();
         // query whether we've to inject the application server instance or not
         if ($listenerInstance instanceof ApplicationServerAwareListenerInterface) {
             $listenerInstance->injectApplicationServer($this);
         }
         // add the listeners
         $emitter->addListener($listener->getEvent(), $listenerInstance);
     }
     // synchronize the emitter
     $this->emitter = $emitter;
     // override the default runlevel with the value found in the bootstrap configuration
     $this->runlevel = $this->runlevelFromString($bootstrapNode->getDefaultRunlevel());
     // flag to keep the server running or to stop it
     $keepRunning = true;
     // initialize the actual runlevel with -1
     $actualRunlevel = -1;
     // start with the default runlevel
     $this->init(null, $this->runlevel);
     do {
         try {
             switch ($this->command) {
                 case InitCommand::COMMAND:
                     // copy command params -> the requested runlevel in that case
                     $this->runlevel = $this->params;
                     if ($this->runlevel == ApplicationServerInterface::REBOOT) {
                         // backup the runlevel
                         $backupRunlevel = $actualRunlevel;
                         // shutdown the application server
                         for ($i = $actualRunlevel; $i >= ApplicationServerInterface::SHUTDOWN; $i--) {
                             $this->emitter->emit(sprintf('leave.runlevel.%s', $this->runlevelToString($i)), $i);
                             // stop the services of the PREVIOUS runlevel
                             $this->doStopServices($i + 1);
                         }
                         // switch back to the runlevel we backed up before
                         for ($z = ApplicationServerInterface::SHUTDOWN; $z <= $backupRunlevel; $z++) {
                             $this->emitter->emit(sprintf('enter.runlevel.%s', $this->runlevelToString($z)), $z);
                         }
                         // set the runlevel to the one before we restart
                         $actualRunlevel = $backupRunlevel;
                         // reset the runlevel and the params
                         $this->runlevel = $this->params = $actualRunlevel;
                     } elseif ($actualRunlevel == ApplicationServerInterface::SHUTDOWN) {
                         // we want to shutdown the application server
                         $keepRunning = false;
                     } elseif ($actualRunlevel < $this->runlevel) {
                         // switch to the requested runlevel
                         for ($i = $actualRunlevel + 1; $i <= $this->runlevel; $i++) {
                             $this->emitter->emit(sprintf('enter.runlevel.%s', $this->runlevelToString($i)), $i);
                         }
                         // set the new runlevel
                         $actualRunlevel = $this->runlevel;
                     } elseif ($actualRunlevel > $this->runlevel) {
                         // switch down to the requested runlevel
                         for ($i = $actualRunlevel; $i >= $this->runlevel; $i--) {
                             $this->emitter->emit(sprintf('leave.runlevel.%s', $this->runlevelToString($i)), $i);
                             // stop the services of the PREVIOUS runlevel
                             $this->doStopServices($i + 1);
                         }
                         // set the new runlevel
                         $actualRunlevel = $this->runlevel;
                     } else {
                         // signal that we've finished switching the runlevels and wait
                         $this->locked = false;
                         $this->command = null;
                         // print a message and wait
                         $this->getSystemLogger()->info(sprintf('Switched to runlevel %s!!!', $actualRunlevel));
                         // wait for a new command
                         $this->synchronized(function ($self) {
                             $self->wait();
                         }, $this);
                     }
                     break;
                 case ModeCommand::COMMAND:
                     // switch the application server mode
                     $this->doSwitchSetupMode($this->params, $this->getConfigurationFilename());
                     // singal that we've finished setting umask and wait
                     $this->locked = false;
                     $this->command = null;
                     // wait for a new command
                     $this->synchronized(function ($self) {
                         $self->wait();
                     }, $this);
                     break;
                 case DoctrineCommand::COMMAND:
                     // execute the Doctrine command
                     $this->result = $this->doDoctrine($this->params);
                     // singal that we've finished setting umask and wait
                     $this->locked = false;
                     $this->command = null;
                     // wait for a new command
                     $this->synchronized(function ($self) {
                         $self->wait();
                     }, $this);
                     break;
                 default:
                     // print a message and wait
                     $this->getSystemLogger()->info('Can\'t find any command!!!');
                     // singal that we've finished setting umask and wait
                     $this->locked = false;
                     // wait for a new command
                     $this->synchronized(function ($self) {
                         $self->wait();
                     }, $this);
                     break;
             }
         } catch (\Exception $e) {
             $this->getSystemLogger()->error($e->getMessage());
         }
     } while ($keepRunning);
 }
예제 #21
0
 /**
  * Loads the events emitter
  *
  * @param Container $container
  * @return Emitter
  */
 private function loadEvents(Container $container)
 {
     $events = (require_once __DIR__ . '/../config/events.php');
     $emitter = new Emitter();
     foreach ($events as $event) {
         $emitter->addListener($event['name'], $event['listener'], isset($event['priority']) ? $event['priority'] : 0);
     }
     return $emitter;
 }
 /**
  * @param EventInterface $event
  */
 public function emit(EventInterface $event)
 {
     $this->emitter->emit($event);
 }
 /**
  * @param \League\Event\Emitter $event
  */
 protected function registerEventListeners(Emitter $event)
 {
     $event->addListener('RouterEvent', function ($event) {
         $event->router->addRoute('GET', '/{fileId:[a-zA-Z0-9_\\-\\/]*}.json', 'Songbird\\Package\\Jsonable\\Handler::__invoke');
     }, 100);
 }
예제 #24
0
 /**
  * @see AbstractDispatcherAdapter::get
  */
 public function get($name)
 {
     return array_map(function (CallbackListener $listener) {
         return $listener->getCallback();
     }, $this->emitter->getListeners($name));
 }
 /**
  * @test
  */
 public function itShouldPublishTheEvent()
 {
     $this->eventPublishingListener->handle($this->message);
     $this->emitter->shouldHaveReceived('emit')->with($this->event);
 }
define('WEBROOT', __DIR__ . DIRECTORY_SEPARATOR . 'webroot');
use Clue\React\Sse\BufferedChannel;
use GuzzleHttp\Client;
use League\Event\Emitter;
use React\EventLoop\Factory;
use React\Filesystem\Filesystem;
use React\Http\Server as HttpServer;
use React\Socket\Server as SocketServer;
use WyriHaximus\React\Examples\HostnameAnalyzer\Listeners\ChannelListener;
use WyriHaximus\React\Examples\HostnameAnalyzer\Listeners\DnsListener;
use WyriHaximus\React\Examples\HostnameAnalyzer\Listeners\GeoListener;
use WyriHaximus\React\Examples\HostnameAnalyzer\Listeners\TitleListener;
use WyriHaximus\React\Examples\HostnameAnalyzer\ResponseHandler;
use WyriHaximus\React\RingPHP\HttpClientAdapter;
require 'vendor/autoload.php';
$loop = Factory::create();
$socket = new SocketServer($loop);
$http = new HttpServer($socket, $loop);
$filesystem = Filesystem::create($loop);
$dns = (new \React\Dns\Resolver\Factory())->createCached('8.8.8.8', $loop);
$guzzle = new Client(['handler' => new HttpClientAdapter($loop, null, $dns)]);
$channel = new BufferedChannel();
$emitter = new Emitter();
$emitter->useListenerProvider(new TitleListener($emitter, $guzzle));
$emitter->useListenerProvider(new DnsListener($emitter, $dns));
$emitter->useListenerProvider(new GeoListener($emitter, $guzzle));
$emitter->useListenerProvider(new ChannelListener($emitter, $channel));
$files = $filesystem->dir(WEBROOT)->ls();
$http->on('request', new ResponseHandler($files, $filesystem, $emitter, $channel));
$socket->listen(1337);
$loop->run();
예제 #27
0
 public function testControllerMustReturnResponse()
 {
     $req = (new Request())->withMethod('GET')->withUri(new Uri('http://test.example.com'));
     $resolved = new ResolvedRoute($req, function () {
         return 'not a response';
     }, StatusCodes::OK);
     $this->mockRouter->expects($this->once())->method('match')->with($this->isInstanceOf(ServerRequestInterface::class))->willReturn($resolved);
     $emitter = new EventEmitter();
     $actual = [null, null];
     $emitter->addListener(Engine::EXCEPTION_THROWN_EVENT, function (ExceptionThrownEvent $event) use(&$actual) {
         $actual = [get_class($event->getException()), $event->getException()->getMessage()];
     });
     $this->runEngine($this->getMockedEngine(null, $emitter), $req, false);
     list($actualType, $actualMsg) = $actual;
     $expectedExcType = InvalidTypeException::class;
     $expectedMsg = "Controller MUST return an instance of Psr\\Http\\Message\\ResponseInterface, \"string\" was returned.";
     $this->assertSame($expectedExcType, $actualType);
     $this->assertSame($expectedMsg, $actualMsg);
 }
예제 #28
0
 /**
  * @param BoardFactory $boardFactory
  *
  * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
  * @throws \React\Socket\ConnectionException
  */
 public function run(BoardFactory $boardFactory)
 {
     $emitter = new Emitter();
     $wamp = new WampConnector($emitter);
     $webSocket = new \React\Socket\Server($this->eventLoop);
     $webSocket->listen(self::SOCKET_LISTEN_PORT, '0.0.0.0');
     $board = $boardFactory->initialize();
     new IoServer(new HttpServer(new WsServer(new WampServer($wamp))), $webSocket);
     $emitter->addListener(QuestionSubscriptionEvent::class, function (QuestionSubscriptionEvent $event) use($wamp, $board) {
         $wamp->onQuestionSubscribe($board->getCategories(), $event->getSessionId());
     });
     $emitter->addListener(ContestantScoreSubscriptionEvent::class, function (ContestantScoreSubscriptionEvent $event) use($wamp, $board) {
         $wamp->onContestantScoreSubscription($board->getContestants(), $event->getSessionId());
     });
     $emitter->addListener(BuzzerStatusSubscriptionEvent::class, function (BuzzerStatusSubscriptionEvent $event) use($wamp, $board) {
         $wamp->onBuzzerStatusChange($board->getBuzzerStatus(), [], [$event->getSessionId()]);
     });
     $emitter->addListener(BuzzerResolutionEvent::class, function (BuzzerResolutionEvent $event) use($wamp) {
         //TODO Store this event
         echo 'Buzzer Resolution: ' . $event->getResolution()->getContestant()->getName() . " buzzed in ({$event->getResolution()->getTime()}ms)\n";
         $wamp->onBuzzerResolution($event->getResolution());
     });
     $emitter->addListener(QuestionAnswerEvent::class, function (QuestionAnswerEvent $event) use($wamp, $board, $emitter) {
         try {
             $questionAnswer = $event->getQuestionAnswer();
             $board->addScore($questionAnswer->getContestant(), $questionAnswer->getRealValue());
             $wamp->onQuestionAnswer($questionAnswer);
         } catch (ContestantNotFoundException $exception) {
             echo $exception->getMessage();
             // TODO handle exception
         }
         if ($questionAnswer->isCorrect()) {
             $emitter->emit(new QuestionDismissalEvent(new QuestionDismissal($questionAnswer->getCategory(), $questionAnswer->getValue())));
             return;
         }
         $emitter->emit(new BuzzerStatusChangeEvent(new BuzzerStatus(true)));
     });
     $emitter->addListener(QuestionDisplayRequestEvent::class, function (QuestionDisplayRequestEvent $event) use($wamp, $board) {
         try {
             $question = $board->getQuestionByCategoryAndValue($event->getCategoryName(), $event->getValue());
             $question->setUsed();
             $wamp->onQuestionDisplay($question, $event->getCategoryName());
         } catch (QuestionNotFoundException $exception) {
             //TODO log this somewhere.
             echo "Error occured, could not find question in category: {$event->getCategoryName()} valued at: {$event->getValue()}";
         }
     });
     $emitter->addListener(DailyDoubleBetEvent::class, function (DailyDoubleBetEvent $event) use($wamp, $board) {
         try {
             $question = $board->getQuestionByCategoryAndValue($event->getCategory(), $event->getValue());
         } catch (QuestionNotFoundException $e) {
             // TODO
         }
         $wamp->onDailyDoubleBetRecieved($question, $event->getCategory(), $event->getBet());
     });
     $emitter->addListener(QuestionDismissalEvent::class, function (QuestionDismissalEvent $event) use($wamp, $board) {
         $dismissal = $event->getDismissal();
         $wamp->onQuestionDismiss($dismissal);
     });
     $emitter->addListener(BuzzReceivedEvent::class, function (BuzzReceivedEvent $event) use($board, $emitter) {
         if (!$board->getBuzzerStatus()->isActive()) {
             // The buzzer isn't active, so there's nothing to do.
             return;
         }
         if ($board->getResolver()->isEmpty()) {
             // If this is the first buzz, then we want to resolve it after the timeout.
             $this->eventLoop->addTimer($this->buzzer_resolve_timeout, function () use($board, $emitter) {
                 $resolution = $board->resolveBuzzes();
                 $emitter->emit(new BuzzerResolutionEvent($resolution));
             });
         }
         // TODO store this event
         echo 'Buzz in (' . $event->getContestant()->getName() . '): ' . $event->getDifference() . "ms \n";
         $board->getResolver()->addBuzz($event);
     });
     $emitter->addListener(BuzzerStatusChangeEvent::class, function (BuzzerStatusChangeEvent $event) use($wamp, $board) {
         $board->setBuzzerStatus($event->getBuzzerStatus());
         $wamp->onBuzzerStatusChange($event->getBuzzerStatus());
     });
     $emitter->addListener(FinalJeopardyCategoryRequest::class, function (FinalJeopardyCategoryRequest $event) use($wamp, $board) {
         $wamp->onFinalJeopardyRequest('category', $board->getFinalJeopardyClue());
     });
     $emitter->addListener(FinalJeopardyClueRequest::class, function (FinalJeopardyClueRequest $event) use($wamp, $board) {
         $wamp->onFinalJeopardyBetCollectionRequest();
         // We're going to wait for a set time
         //TODO this doesn't work for some reason in every case, so we simply don't close the acceptance of responses.
         $this->eventLoop->addTimer($this->final_jeopardy_collection_timeout, function () use($wamp, $board) {
             if (!$board->getFinalJeopardy()->hasAllBets()) {
                 //TODO logging
                 echo "Did not recieve all bets.\n";
                 $missingbets = $board->getFinalJeopardy()->getMissingBets();
                 $missingbets = implode(', ', $missingbets);
                 echo "Require bets from: {$missingbets}\n";
             }
             $wamp->onFinalJeopardyRequest('clue', $board->getFinalJeopardyClue());
         });
     });
     $emitter->addListener(ContestantScoreChangeEvent::class, function (ContestantScoreChangeEvent $event) use($wamp, $board) {
         try {
             $board->addScore(new Contestant($event->getContestant()), $event->getScoreChange());
         } catch (ContestantNotFoundException $e) {
             //TODO
         }
         $contestant = $board->getContestants()->first(function ($key, Contestant $contestant) use($event) {
             return $contestant->getName() === $event->getContestant();
         });
         $wamp->onContestantScoreUpdate($contestant);
     });
     $emitter->addListener(FinalJeopardyBetEvent::class, function (FinalJeopardyBetEvent $event) use($wamp, $board) {
         $finalJeopardy = $board->getFinalJeopardy();
         $finalJeopardy->setBet($event->getContestant(), $event->getBet());
     });
     $emitter->addListener(FinalJeopardyAnswerRequest::class, function (FinalJeopardyAnswerRequest $event) use($wamp, $board) {
         $wamp->onFinalJeopardyAnswerCollectionRequest();
         $this->eventLoop->addTimer($this->final_jeopardy_collection_timeout, function () use($wamp, $board) {
             if (!$board->getFinalJeopardy()->hasAllAnswers()) {
                 //TODO logging
                 echo "Did not receive all final jeopardy answers!\n";
                 $missingAnswers = $board->getFinalJeopardy()->getMissingAnswers();
                 $missingAnswers = implode(', ', $missingAnswers);
                 echo "Require answers from: {$missingAnswers}\n";
             }
             $wamp->onFinalJeopardyRequest('answer', $board->getFinalJeopardyClue());
         });
     });
     $emitter->addListener(FinalJeopardyAnswerEvent::class, function (FinalJeopardyAnswerEvent $event) use($wamp, $board) {
         $finalJeopardy = $board->getFinalJeopardy();
         if ($finalJeopardy->hasAnswer($event->getContestant())) {
             //TODO logging
             echo "{$event->getContestant()} has already submitted a final answer";
             return;
         }
         $finalJeopardy->setAnswer($event->getContestant(), $event->getAnswer());
     });
     $emitter->addListener(FinalJeopardyResponseRequest::class, function (FinalJeopardyResponseRequest $event) use($wamp, $board) {
         $finalJeopardy = $board->getFinalJeopardy();
         if (!$finalJeopardy->hasAnswer($event->getContestant())) {
             //TODO logging
             $response = new FinalJeopardyQuestionResponse($event->getContestant(), 0, 'No answer, Troy');
             $wamp->onFinalJeopardyResponse($response);
             return;
         }
         $wamp->onFinalJeopardyResponse($finalJeopardy->getResponse($event->getContestant()));
     });
     $this->eventLoop->run();
 }
 protected function handleLookup(Response $response, $hostName)
 {
     $this->emitter->emit('lookup', $hostName);
     $response->writeHead(200);
     $response->end('{}');
 }