/** * @param SessionEvent $event */ public function onOpen(SessionEvent $event) { /* @var $mapping \Voryx\ThruwayBundle\Mapping\URIClassMapping */ foreach ($event->getResourceMappings() as $name => $mapping) { $annotation = $mapping->getAnnotation(); if (!$annotation instanceof Register) { continue; } $topicStateHandler = $annotation->getTopicStateHandlerFor(); if (!$topicStateHandler) { continue; } $session = $event->getSession(); $registration = new \stdClass(); $registration->handler_uri = $annotation->getName(); $registration->uri = $annotation->getTopicStateHandlerFor(); $registration->options = $annotation->getTopicStateHandlerOptions(); //Register Topic Handlers $registration->topic = $topicStateHandler; $session->call('add_state_handler', [$registration])->then(function ($res) use($annotation) { Logger::info($this, "Registered topic handler RPC: '{$annotation->getName()}'' for topic: '{$annotation->getTopicStateHandlerFor()}'"); }, function (ErrorMessage $error) use($annotation) { Logger::error($this, "Unable to register topic handler RPC: '{$annotation->getName()}'' for topic: '{$annotation->getTopicStateHandlerFor()}'' Error: '{$error->getErrorURI()}''"); }); } }
/** * Start transport provider * * @param \Thruway\Peer\ClientInterface $client * @param \React\EventLoop\LoopInterface $loop */ public function startTransportProvider(ClientInterface $client, LoopInterface $loop) { Logger::info($this, "Starting Transport"); $this->client = $client; $this->loop = $loop; $this->connector = new Factory($this->loop); $this->connector->__invoke($this->URL, ['wamp.2.json'])->then(function (WebSocket $conn) { Logger::info($this, "Pawl has connected"); $transport = new PawlTransport($conn, $this->loop); $transport->setSerializer(new JsonSerializer()); $this->client->onOpen($transport); $conn->on('message', function ($msg) use($transport) { Logger::debug($this, "Received: {$msg}"); try { $this->client->onMessage($transport, $transport->getSerializer()->deserialize($msg)); } catch (DeserializationException $e) { Logger::warning($this, "Deserialization exception occurred."); } catch (\Exception $e) { Logger::warning($this, "Exception occurred during onMessage: " . $e->getMessage()); } }); $conn->on('close', function ($conn) { Logger::info($this, "Pawl has closed"); $this->client->onClose('close'); }); $conn->on('pong', function ($frame, $ws) use($transport) { $transport->onPong($frame, $ws); }); }, function ($e) { $this->client->onClose('unreachable'); Logger::info($this, "Could not connect: {$e->getMessage()}"); // $this->loop->stop(); }); }
public function handleRouterStart(RouterStartEvent $event) { $socket = new Server($this->loop); $socket->on('connection', [$this, "handleConnection"]); Logger::info($this, "Raw socket listening on " . $this->address . ":" . $this->port); $socket->listen($this->port, $this->address); $this->server = $socket; }
public function handleRouterStart(RouterStartEvent $event) { $server = new Server($this->bindAddress, $this->port, false, ["wamp.2.json"]); Logger::info($this, "Websocket listening on " . $this->bindAddress . ":" . $this->port); $this->serverDisposable = $server->subscribe(new CallbackObserver(function (MessageSubject $ms) { $this->createNewSessionForMessageSubject($ms); }, function (\Exception $err) { Logger::error($this, "Received error on server: " . $err->getMessage()); }, function () { Logger::alert($this, "Completed. Not sure if we should ever do that."); })); }
/** * Get Authenticate message from challenge message * * @param \Thruway\Message\ChallengeMessage $msg * @return \Thruway\Message\AuthenticateMessage|boolean */ public function getAuthenticateFromChallenge(ChallengeMessage $msg) { Logger::info($this, "Got challenge"); Logger::debug($this, "Challenge Message: " . json_encode($msg)); if (!in_array($msg->getAuthMethod(), $this->getAuthMethods())) { //throw new \Exception("method isn't in methods"); return false; } if (!is_array($msg->getDetails())) { Logger::info($this, "No details sent with challenge"); return false; } $challenge = ''; if (isset($msg->getDetails()['challenge'])) { $challenge = $msg->getDetails()['challenge']; } else { Logger::info($this, "No challenge for wampcra?"); return false; } $keyToUse = $this->key; if (isset($msg->getDetails()['salt'])) { // we need a salted key $salt = $msg->getDetails()['salt']; $keyLen = 32; if (isset($msg->getDetails()['keylen'])) { if (is_numeric($msg->getDetails()['keylen'])) { $keyLen = $msg->getDetails()['keylen']; } else { Logger::error($this, "keylen is not numeric."); } } $iterations = 1000; if (isset($msg->getDetails()['iterations'])) { if (is_numeric($msg->getDetails()['iterations'])) { $iterations = $msg->getDetails()['iterations']; } else { Logger::error($this, "iterations is not numeric."); } } $keyToUse = $this->getDerivedKey($this->key, $salt, $iterations, $keyLen); } $token = base64_encode(hash_hmac('sha256', $challenge, $keyToUse, true)); $authMessage = new AuthenticateMessage($token); Logger::debug($this, "returning: " . json_encode($authMessage)); return $authMessage; }
/** * @param \Thruway\Event\MessageEvent $event * @throws \Exception */ public function handlePreHelloMessage(MessageEvent $event) { Logger::info($this, "Got prehello..."); /** @var HelloMessage $msg */ $msg = $event->message; $session = $event->session; $session->setHelloMessage($msg); try { $realm = $this->getRealm($msg->getRealm()); $realm->addSession($session); } catch (\Exception $e) { // TODO: Test this $errorUri = "wamp.error.unknown"; $description = $e->getMessage(); if ($e instanceof InvalidRealmNameException || $e instanceof RealmNotFoundException) { $errorUri = "wamp.error.no_such_realm"; } $session->abort(['description' => $description], $errorUri); } }
/** * Process Welcome message * * @param \Thruway\ClientSession $session * @param \Thruway\Message\WelcomeMessage $msg */ public function processWelcome(ClientSession $session, WelcomeMessage $msg) { Logger::info($this, "We have been welcomed..."); //TODO: I'm sure that there are some other things that we need to do here $session->setSessionId($msg->getSessionId()); $this->emit('open', [$session, $this->transport, $msg->getDetails()]); $session->setState(Session::STATE_UP); }
/** * Process InvocationMessage * * @param \Thruway\ClientSession $session * @param \Thruway\Message\InvocationMessage $msg */ protected function processInvocation(ClientSession $session, InvocationMessage $msg) { foreach ($this->registrations as $key => $registration) { if (!isset($registration["registration_id"])) { Logger::info($this, "Registration_id not set for " . $registration['procedure_name']); } else { if ($registration["registration_id"] === $msg->getRegistrationId()) { if ($registration['callback'] === null) { // this is where calls end up if the client has called unregister but // have not yet received confirmation from the router about the // unregistration $session->sendMessage(ErrorMessage::createErrorMessageFromMessage($msg)); return; } try { $results = $registration["callback"]($msg->getArguments(), $msg->getArgumentsKw(), $msg->getDetails()); if ($results instanceof Promise) { $this->processResultAsPromise($results, $msg, $session, $registration); } else { $this->processResultAsArray($results, $msg, $session); } } catch (\Exception $e) { $errorMsg = ErrorMessage::createErrorMessageFromMessage($msg); $errorMsg->setErrorURI($registration['procedure_name'] . '.error'); $errorMsg->setArguments([$e->getMessage()]); $errorMsg->setArgumentsKw($e); $session->sendMessage($errorMsg); } break; } } } }
/** * @param \Thruway\Session $session * @param \Thruway\Message\Message $msg */ public function processGoodbye(Session $session, Message $msg) { Logger::info($this, "Received a GoodBye, so shutting the session down"); $session->sendMessage(new GoodbyeMessage(new \stdClass(), "wamp.error.goodbye_and_out")); $session->shutdown(); }
/** * Set manager * * @param \Thruway\Manager\ManagerInterface $manager */ public function setManager(ManagerInterface $manager) { $this->manager = $manager; Logger::info($this, "Manager attached to PawlTransportProvider"); }
/** * Handle process received message * * @param \Thruway\Session $session * @param \Thruway\Message\Message $msg */ public function onMessage(Session $session, Message $msg) { if ($msg instanceof GoodByeMessage) { Logger::info($this, "Received a GoodBye, so shutting the session down"); $session->sendMessage(new GoodbyeMessage(new \stdClass(), "wamp.error.goodbye_and_out")); $session->shutdown(); } elseif ($session->isAuthenticated()) { $this->processAuthenticated($session, $msg); } elseif ($msg instanceof AbortMessage) { $this->processAbort($session, $msg); } elseif ($msg instanceof HelloMessage) { $this->processHello($session, $msg); } elseif ($msg instanceof AuthenticateMessage) { $this->processAuthenticate($session, $msg); } else { Logger::error($this, "Unhandled message sent to unauthenticated realm: " . $msg->getMsgCode()); $session->abort(new \stdClass(), "wamp.error.not_authorized"); } }
/** * Start router * * @param bool $runLoop * @throws \Exception */ public function start($runLoop = true) { Logger::info($this, "Starting router"); if ($this->loop === null) { throw new \Exception("Loop is null"); } $this->started = true; $this->eventDispatcher->dispatch("router.start", new RouterStartEvent()); if ($runLoop) { Logger::info($this, "Starting loop"); $this->loop->run(); } }
/** * Start router * * @throws \Exception */ public function start() { Logger::info($this, "Starting router"); if ($this->loop === null) { throw new \Exception("Loop is null"); } if (count($this->transportProviders) == 0) { throw new \Exception("No transport providers specified."); } foreach ($this->transportProviders as $transportProvider) { Logger::info($this, "Starting transport provider " . get_class($transportProvider)); $transportProvider->setManager($this->manager); $transportProvider->startTransportProvider($this, $this->loop); } $this->setupManager(); Logger::info($this, "Starting loop"); $this->loop->run(); }
/** * Set authenticated state * * @param boolean $authenticated */ public function setAuthenticated($authenticated) { // make sure the metaevent is only sent when changing from // not-authenticate to authenticated if ($authenticated && !$this->authenticated) { // metaevent $metaInfo = $this->getMetaInfo(); $this->getRealm()->publishMeta('wamp.metaevent.session.on_join', [$metaInfo]); Logger::info($this, "Session joined: " . json_encode($metaInfo)); } parent::setAuthenticated($authenticated); }
public function handleRouterStart(RouterStartEvent $event) { $ws = new WsServer($this); $ws->disableVersion(0); $socket = new Reactor($this->loop); $socket->listen($this->port, $this->address); Logger::info($this, "Websocket listening on " . $this->address . ":" . $this->port); $this->server = new IoServer(new HttpServer($ws), $socket, $this->loop); }
/** * Add new realm * * @param \Thruway\Realm $realm * @throws \Thruway\Exception\InvalidRealmNameException * @throws \Exception */ public function addRealm(Realm $realm) { $realmName = $realm->getRealmName(); if (!static::validRealmName($realm->getRealmName())) { throw new InvalidRealmNameException(); } if (array_key_exists($realm->getRealmName(), $this->realms)) { throw new \Exception("There is already a realm \"" . $realm->getRealmName() . "\""); } Logger::debug($this, "Adding realm \"" . $realmName . "\""); if ($realm->getManager() instanceof ManagerDummy) { /** remind people that we don't setup the manager for them if they * are creating their own realms */ Logger::info($this, "Realm \"" . $realmName . "\" is using ManagerDummy"); } $this->realms[$realm->getRealmName()] = $realm; $this->router->getEventDispatcher()->dispatch('new_realm', new NewRealmEvent($realm)); }