/** * Processes the request by invoking the request handler that executes the servlet * in a protected context. * * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance * * @return void */ public function invoke(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { try { // unpack the remote method call $remoteMethod = RemoteMethodProtocol::unpack($servletRequest->getBodyContent()); // load the application context /** @var \AppserverIo\Appserver\Application\Application $application */ $application = $servletRequest->getContext(); // prepare method name and parameters and invoke method $className = $remoteMethod->getClassName(); $methodName = $remoteMethod->getMethodName(); $parameters = $remoteMethod->getParameters(); $sessionId = $remoteMethod->getSessionId(); // load the bean manager and the bean instance $instance = $application->search($className, array($sessionId, array($application))); // invoke the remote method call on the local instance $response = call_user_func_array(array($instance, $methodName), $parameters); // serialize the remote method and write it to the socket $servletResponse->appendBodyStream(RemoteMethodProtocol::pack($response)); // re-attach the bean instance in the container and unlock it $application->search('BeanContextInterface')->attach($instance, $sessionId); } catch (\Exception $e) { // catch the exception and append it to the body stream $servletResponse->appendBodyStream(RemoteMethodProtocol::pack(RemoteExceptionWrapper::factory($e))); } // finally dispatch this request, because we have finished processing it $servletRequest->setDispatched(true); }
/** * Processes the request by invoking the request handler that executes the servlet * in a protected context. * * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance * * @return void */ public function invoke(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { try { // unpack the remote method call $remoteMethod = RemoteMethodProtocol::unpack($servletRequest->getBodyContent()); // load the application context /** @var \AppserverIo\Appserver\Application\Application $application */ $application = $servletRequest->getContext(); // invoke the remote method and re-attach the bean instance to the container $response = $application->search(BeanContextInterface::IDENTIFIER)->invoke($remoteMethod, new ArrayList()); // serialize the remote method and write it to the socket $servletResponse->appendBodyStream(RemoteMethodProtocol::pack($response)); } catch (\Exception $e) { // catch the exception and append it to the body stream $servletResponse->appendBodyStream(RemoteMethodProtocol::pack(RemoteExceptionWrapper::factory($e))); } // finally dispatch this request, because we have finished processing it $servletRequest->setDispatched(true); }
/** * Parses the request body and tries to unpack the remote method * instance from it. * * @param \AppserverIo\Psr\Socket\SocketInterface $connection The package remote method instance * @param integer $contentLength The content length to read * * @return object The unpacked remote method object/result */ public function parseBody(SocketInterface $connection, $contentLength) { $rawResponse = stream_get_contents($connection->getConnectionResource(), $contentLength); return RemoteMethodProtocol::unpack($rawResponse); }
/** * 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; }