/** * Sends the remote method call to the container instance. * * @param \AppserverIo\RemoteMethodInvocation\RemoteMethodInterface $remoteMethod The remote method instance * * @return mixed The response from the container * @see AppserverIo\RemoteMethodInvocation\ConnectionInterface::send() * * @throws \Exception */ public function send(RemoteMethodInterface $remoteMethod) { // set address + port + appName $remoteMethod->setAddress($this->getAddress()); $remoteMethod->setPort($this->getPort()); $remoteMethod->setAppName($this->getAppName()); // serialize the remote method and write it to the socket $packed = RemoteMethodProtocol::pack($remoteMethod); // performs the HTTP POST $opts = array('http' => array('method' => 'POST', 'header' => 'Content-type: text/plain', 'content' => $packed)); // create the context $context = stream_context_create($opts); // invoke a HTTP request and try to read the response from the remote server if ($fp = fopen($url = $this->getBaseUrl($this->getPath()), 'r', false, $context)) { // initialize the response $response = ''; // read while content is available while ($row = fgets($fp)) { $response .= trim($row); } } else { throw new \Exception('Unable to connect to ' . $url); } // read the remote method call result $result = RemoteMethodProtocol::unpack($response); // if an exception returns, throw it again if ($result instanceof RemoteExceptionWrapper) { throw $result->toException(); } // close the connection and return the data return $result; }
/** * Invoke the passed remote method on the described session bean and return the result. * * @param \AppserverIo\RemoteMethodInvocation\RemoteMethodInterface $remoteMethod The remote method description * @param \AppserverIo\Collections\CollectionInterface $sessions The collection with the sessions * * @return mixed The result of the remote method invocation */ public function invoke(RemoteMethodInterface $remoteMethod, CollectionInterface $sessions) { // prepare method name and parameters and invoke method $className = $remoteMethod->getClassName(); $methodName = $remoteMethod->getMethodName(); $parameters = $remoteMethod->getParameters(); $sessionId = $remoteMethod->getSessionId(); // load the application instance $application = $this->getApplication(); // try to load the session with the ID passed in the remote method $session = CollectionUtils::find($sessions, new FilterSessionPredicate($sessionId)); // query whether the session is available or not if ($session instanceof CollectionInterface) { // query whether we already have an instance in the session container if ($instance = $session->exists($className)) { $instance = $session->get($className); } } // load a fresh bean instance and add it to the session container if ($instance == null) { $instance = $application->getNamingDirectory()->search($className); } // query whether we already have an instance in the session container if ($session instanceof CollectionInterface) { $session->add($className, $instance); } // invoke the remote method call on the local instance return call_user_func_array(array($instance, $methodName), $parameters); }
/** * Invoke the passed remote method on the described session bean and return the result. * * @param \AppserverIo\RemoteMethodInvocation\RemoteMethodInterface $remoteMethod The remote method description * @param \AppserverIo\Collections\CollectionInterface $sessions The collection with the sessions * * @return mixed The result of the remote method invocation */ public function invoke(RemoteMethodInterface $remoteMethod, CollectionInterface $sessions) { // prepare method name and parameters and invoke method $className = $remoteMethod->getClassName(); $methodName = $remoteMethod->getMethodName(); $parameters = $remoteMethod->getParameters(); $sessionId = $remoteMethod->getSessionId(); // load the application instance $application = $this->getApplication(); // try to load the session with the ID passed in the remote method $session = CollectionUtils::find($sessions, new FilterSessionPredicate($sessionId)); // query whether the session is available or not if ($session instanceof CollectionInterface) { // query whether we already have an instance in the session container if ($instance = $session->exists($className)) { $instance = $session->get($className); } } // load a fresh bean instance and add it to the session container if ($instance == null) { $instance = $application->search($className, array($sessionId, array($application))); } // query whether we already have an instance in the session container if ($session instanceof CollectionInterface) { $session->add($className, $instance); } // invoke the remote method call on the local instance $response = call_user_func_array(array($instance, $methodName), $parameters); // load the object manager $objectManager = $application->search(ObjectManagerInterface::IDENTIFIER); // load the bean descriptor $descriptor = $objectManager->getObjectDescriptors()->get(get_class($instance)); // initialize the flag to mark the instance to be re-attached $attach = true; // query if we've stateful session bean if ($descriptor instanceof StatefulSessionBeanDescriptorInterface) { // remove the SFSB instance if a remove method has been called if ($descriptor->isRemoveMethod($methodName)) { $this->removeStatefulSessionBean($sessionId, $descriptor->getClassName()); $attach = false; // query whether the session is available or not if ($session instanceof CollectionInterface) { $session->remove($className); } } } // re-attach the bean instance if necessary if ($attach === true) { $this->attach($instance, $sessionId); } // return the remote method call result return $response; }