sendMessage() public method

Send message
public sendMessage ( Thruway\Message\Message $msg ) : mixed | void
$msg Thruway\Message\Message
return mixed | void
Example #1
0
 private function processInvocationError(Session $session, ErrorMessage $msg)
 {
     $call = $this->getCallByRequestId($msg->getRequestId());
     if (!$call) {
         $errorMsg = ErrorMessage::createErrorMessageFromMessage($msg);
         $this->manager->error('No call for invocation error message: ' . $msg->getRequestId());
         // TODO: do we send a message back to the callee?
         $errorMsg->setErrorURI('wamp.error.no_such_procedure');
         $session->sendMessage($errorMsg);
         return false;
     }
     $this->calls->detach($call);
     $errorMsg = ErrorMessage::createErrorMessageFromMessage($call->getCallMessage());
     $errorMsg->setErrorURI($msg->getErrorURI());
     $errorMsg->setArguments($msg->getArguments());
     $errorMsg->setArgumentsKw($msg->getArgumentsKw());
     $call->getCallerSession()->sendMessage($errorMsg);
 }
Example #2
0
 /**
  * Process call
  *
  * @param \Thruway\Session $session
  * @param Call $call
  * @throws \Exception
  * @return bool | Call
  */
 public function processCall(Session $session, Call $call)
 {
     // find a registration to call
     if (count($this->registrations) == 0) {
         $session->sendMessage(ErrorMessage::createErrorMessageFromMessage($call->getCallMessage(), 'wamp.error.no_such_procedure'));
         return false;
     }
     // just send it to the first one if we don't allow multiple registrations
     if (!$this->getAllowMultipleRegistrations()) {
         $this->registrations[0]->processCall($call);
     } else {
         $this->callQueue->enqueue($call);
         $this->processQueue();
     }
     return true;
 }
Example #3
0
 /**
  * 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");
     }
 }
Example #4
0
 /**
  * @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();
 }
Example #5
0
 /**
  * processCancel processes cancel message from the caller.
  * Return true if the Call should be removed from active calls
  *
  * @param Session $session
  * @param CancelMessage $msg
  * @return bool
  */
 public function processCancel(Session $session, CancelMessage $msg)
 {
     if ($this->getCallerSession() !== $session) {
         Logger::warning($this, "session attempted to cancel call they did not own.");
         return false;
     }
     if ($this->getCalleeSession() === null) {
         // this call has not been sent to a callee yet (it is in a queue)
         // we can just kill it and say it was canceled
         $errorMsg = ErrorMessage::createErrorMessageFromMessage($msg, "wamp.error.canceled");
         $details = $errorMsg->getDetails() ?: (object) [];
         $details->_thruway_removed_from_queue = true;
         $session->sendMessage($errorMsg);
         return true;
     }
     $details = (object) [];
     if ($this->getCalleeSession()->getHelloMessage() instanceof HelloMessage) {
         $details = $this->getCalleeSession()->getHelloMessage()->getDetails();
     }
     $calleeSupportsCancel = false;
     if (isset($details->roles->callee->features->call_canceling) && is_scalar($details->roles->callee->features->call_canceling)) {
         $calleeSupportsCancel = (bool) $details->roles->callee->features->call_canceling;
     }
     if (!$calleeSupportsCancel) {
         $errorMsg = ErrorMessage::createErrorMessageFromMessage($msg);
         $errorMsg->setErrorURI('wamp.error.not_supported');
         $session->sendMessage($errorMsg);
         return false;
     }
     $this->setCancelMessage($msg);
     $this->canceling = true;
     $calleeSession = $this->getCalleeSession();
     $interruptMessage = new InterruptMessage($this->getInvocationRequestId(), (object) []);
     $calleeSession->sendMessage($interruptMessage);
     $this->setInterruptMessage($interruptMessage);
     if (isset($msg->getOptions()->mode) && is_scalar($msg->getOptions()->mode) && $msg->getOptions()->mode == "killnowait") {
         $errorMsg = ErrorMessage::createErrorMessageFromMessage($msg, "wamp.error.canceled");
         $session->sendMessage($errorMsg);
         return true;
     }
     return false;
 }
Example #6
0
 /**
  * Process InvocationError
  *
  * @param \Thruway\Session $session
  * @param \Thruway\Message\ErrorMessage $msg
  */
 private function processInvocationError(Session $session, ErrorMessage $msg)
 {
     //$call = $this->getCallByRequestId($msg->getRequestId());
     $call = $this->callInvocationIndex[$msg->getRequestId()];
     if (!$call) {
         $errorMsg = ErrorMessage::createErrorMessageFromMessage($msg);
         Logger::error($this, 'No call for invocation error message: ' . $msg->getRequestId());
         // TODO: do we send a message back to the callee?
         $errorMsg->setErrorURI('wamp.error.no_such_procedure');
         $session->sendMessage($errorMsg);
         return;
     }
     if ($call->getCalleeSession() !== $session) {
         Logger::error($this, "Attempted Invocation Error from session that does not own the call");
         return;
     }
     $call->getRegistration()->removeCall($call);
     $this->removeCall($call);
     $errorMsg = ErrorMessage::createErrorMessageFromMessage($call->getCallMessage());
     $errorMsg->setErrorURI($msg->getErrorURI());
     $errorMsg->setArguments($msg->getArguments());
     $errorMsg->setArgumentsKw($msg->getArgumentsKw());
     // not sure if this detail should pass through
     $errorMsg->setDetails($msg->getDetails());
     $call->getCallerSession()->sendMessage($errorMsg);
 }
Example #7
0
 /**
  * @param Session $session
  * @param UnsubscribeMessage $msg
  * @return UnsubscribedMessage
  */
 public function processUnsubscribe(Session $session, UnsubscribeMessage $msg)
 {
     $subscription = $this->getSubscriptionById($msg->getSubscriptionId());
     if (!$subscription || !isset($this->topics[$subscription->getTopic()])) {
         $errorMsg = ErrorMessage::createErrorMessageFromMessage($msg);
         $session->sendMessage($errorMsg->setErrorURI('wamp.error.no_such_subscription'));
     }
     $topicName = $subscription->getTopic();
     $subscribers = $this->topics[$topicName];
     /* @var $subscriber Session */
     foreach ($this->topics[$topicName] as $key => $subscriber) {
         if ($subscriber == $session) {
             unset($subscribers[$key]);
         }
     }
     $this->subscriptions->detach($subscription);
     $session->sendMessage(new UnsubscribedMessage($msg->getRequestId()));
 }
 /**
  * Call the handler that was registered to handle the Authenticate Message
  *
  * @param $authMethod
  * @param $authMethodInfo
  * @param Realm $realm
  * @param Session $session
  * @param AuthenticateMessage $msg
  */
 private function onAuthenticateHandler($authMethod, $authMethodInfo, Realm $realm, Session $session, AuthenticateMessage $msg)
 {
     $onAuthenticateSuccess = function ($res) use($realm, $session) {
         if (count($res) < 1) {
             $session->abort(new \stdClass(), "thruway.error.authentication_failure");
             return;
         }
         // we should figure out a way to have the router send the welcome
         // message so that the roles and extras that go along with it can be
         // filled in
         if ($res[0] == "SUCCESS") {
             $welcomeDetails = new \stdClass();
             if (isset($res[1]->authid)) {
                 $session->getAuthenticationDetails()->setAuthId($res[1]->authid);
             } else {
                 $session->getAuthenticationDetails()->setAuthId('authenticated_user');
             }
             $authRole = 'authenticated_user';
             $session->getAuthenticationDetails()->addAuthRole($authRole);
             if (isset($res[1]->authroles)) {
                 $session->getAuthenticationDetails()->addAuthRole($res[1]->authroles);
             }
             if (isset($res[1]->authrole)) {
                 $session->getAuthenticationDetails()->addAuthRole($res[1]->authrole);
             }
             if (isset($res[1]->_thruway_authextra)) {
                 $session->getAuthenticationDetails()->setAuthExtra($res[1]->_thruway_authextra);
             }
             if (isset($res[1]) && is_object($res[1])) {
                 $res[1]->authrole = $session->getAuthenticationDetails()->getAuthRole();
                 $res[1]->authroles = $session->getAuthenticationDetails()->getAuthRoles();
                 $res[1]->authid = $session->getAuthenticationDetails()->getAuthId();
                 foreach ($res[1] as $k => $v) {
                     $welcomeDetails->{$k} = $v;
                 }
             }
             $session->setAuthenticated(true);
             $session->sendMessage(new WelcomeMessage($session->getSessionId(), $welcomeDetails));
         } else {
             $session->abort(new \stdClass(), "thruway.error.authentication_failure");
         }
     };
     $onAuthenticateError = function () use($session) {
         Logger::error($this, "onauthenticate rejected the promise");
         $session->abort("thruway.error.unknown");
     };
     $extra = new \stdClass();
     $extra->challenge_details = $session->getAuthenticationDetails()->getChallengeDetails();
     $arguments = new \stdClass();
     $arguments->extra = $extra;
     $arguments->authid = $session->getAuthenticationDetails()->getAuthId();
     $arguments->challenge = $session->getAuthenticationDetails()->getChallenge();
     $arguments->signature = $msg->getSignature();
     $arguments->authmethod = $authMethod;
     $arguments->hello_message = $session->getHelloMessage();
     // now we send our authenticate information to the RPC
     $onAuthenticateHandler = $authMethodInfo['handlers']->onauthenticate;
     $this->session->call($onAuthenticateHandler, [$arguments])->then($onAuthenticateSuccess, $onAuthenticateError);
 }
Example #9
0
 /**
  * Process subscribe message
  *
  * @param \Thruway\Session $session
  * @param \Thruway\Message\SubscribeMessage $msg
  * @throws \Exception
  */
 protected function processSubscribe(Session $session, SubscribeMessage $msg)
 {
     // get a subscription group "hash"
     /** @var MatcherInterface $matcher */
     $matcher = $this->getMatcherForMatchType($msg->getMatchType());
     if ($matcher === null) {
         Logger::alert($this, "no matching match type for \"" . $msg->getMatchType() . "\" for URI \"" . $msg->getUri() . "\"");
         return;
     }
     if (!$matcher->uriIsValid($msg->getUri(), $msg->getOptions())) {
         $errorMsg = ErrorMessage::createErrorMessageFromMessage($msg);
         $session->sendMessage($errorMsg->setErrorURI('wamp.error.invalid_uri'));
         return;
     }
     $matchHash = $matcher->getMatchHash($msg->getUri(), $msg->getOptions());
     if (!isset($this->subscriptionGroups[$matchHash])) {
         $this->subscriptionGroups[$matchHash] = new SubscriptionGroup($matcher, $msg->getUri(), $msg->getOptions());
     }
     /** @var SubscriptionGroup $subscriptionGroup */
     $subscriptionGroup = $this->subscriptionGroups[$matchHash];
     $subscription = $subscriptionGroup->processSubscribe($session, $msg);
     $registry = $this->getStateHandlerRegistry();
     if ($registry !== null) {
         $registry->processSubscriptionAdded($subscription);
     }
 }
Example #10
0
 /**
  * @param Session $session
  * @param UnsubscribeMessage $msg
  * @return bool|Subscription
  */
 public function processUnsubscribe(Session $session, UnsubscribeMessage $msg)
 {
     if ($this->containsSubscriptionId($msg->getSubscriptionId())) {
         /** @var Subscription $subscription */
         $subscription = $this->subscriptions[$msg->getSubscriptionId()];
         if ($session !== $subscription->getSession()) {
             Logger::alert($this, "Unsubscribe request from non-owner: " . json_encode($msg));
             return false;
         }
         $this->removeSubscription($subscription);
         $session->sendMessage(new UnsubscribedMessage($msg->getRequestId()));
         return $subscription;
     }
     return false;
 }
 /**
  * Handle Authenticate message
  *
  * @param \Thruway\Realm $realm
  * @param \Thruway\Session $session
  * @param \Thruway\Message\AuthenticateMessage $msg
  * @throws \Exception
  */
 public function handleAuthenticateMessage(Realm $realm, Session $session, AuthenticateMessage $msg)
 {
     if ($session->getAuthenticationDetails() === null) {
         throw new \Exception('Authenticate with no previous auth details');
     }
     $authMethod = $session->getAuthenticationDetails()->getAuthMethod();
     // find the auth method
     foreach ($this->authMethods as $am => $authMethodInfo) {
         if ($authMethod == $am) {
             // found it
             // now we send our authenticate information to the RPC
             $this->getCaller()->call($this->session, $authMethodInfo['handlers']['onauthenticate'], ['authmethod' => $authMethod, 'challenge' => $session->getAuthenticationDetails()->getChallenge(), 'extra' => ['challenge_details' => $session->getAuthenticationDetails()->getChallengeDetails()], 'signature' => $msg->getSignature(), 'authid' => $session->getAuthenticationDetails()->getAuthId()])->then(function ($res) use($session) {
                 //                        if (!is_array($res)) {
                 //                            return;
                 //                        }
                 if (count($res) < 1) {
                     return;
                 }
                 // we should figure out a way to have the router send the welcome
                 // message so that the roles and extras that go along with it can be
                 // filled in
                 if ($res[0] == "SUCCESS") {
                     $welcomeDetails = ["roles" => []];
                     if (isset($res[1]) && isset($res[1]['authid'])) {
                         $session->getAuthenticationDetails()->setAuthId($res[1]['authid']);
                     } else {
                         $session->getAuthenticationDetails()->setAuthId('authenticated_user');
                         $res[1]['authid'] = $session->getAuthenticationDetails()->getAuthId();
                     }
                     $authRole = 'authenticated_user';
                     $session->getAuthenticationDetails()->addAuthRole($authRole);
                     if (isset($res[1]) && isset($res[1]['authroles'])) {
                         $session->getAuthenticationDetails()->addAuthRole($res[1]['authroles']);
                         $authRole = $session->getAuthenticationDetails()->getAuthRole();
                     }
                     if (isset($res[1]) && isset($res[1]['authrole'])) {
                         $session->getAuthenticationDetails()->addAuthRole($res[1]['authrole']);
                     }
                     if (isset($res[1])) {
                         $res[1]['authrole'] = $session->getAuthenticationDetails()->getAuthRole();
                         $res[1]['authroles'] = $session->getAuthenticationDetails()->getAuthRoles();
                         $res[1]['authid'] = $session->getAuthenticationDetails()->getAuthId();
                         if (is_array($res[1])) {
                             $welcomeDetails = array_merge($welcomeDetails, $res[1]);
                         }
                     }
                     $session->setAuthenticated(true);
                     $session->sendMessage(new WelcomeMessage($session->getSessionId(), $welcomeDetails));
                 } else {
                     $session->abort(new \stdClass(), "bad.login");
                 }
             }, function () use($session) {
                 Logger::error($this, "onauthenticate rejected the promise");
                 $session->abort("thruway.error.unknown");
             });
         }
     }
 }