/**
  * 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;
 }