private function runMethodForRequest(Request $request) { $methodType = self::$messageTypeToMethodType[$request->getType()]; $method = $this->getMethod($request->getMethodName(), $methodType); $arguments = $this->serializer->unserializeArguments($request->getMethodName(), $request->getArgumentsBody(), $request->getHeaders()->get('content-type')); $response = new Response(); $headers = clone $this->headers; $response->setHeaders($headers); switch ($methodType) { case MethodTypes::BASIC: try { $result = $method->call($arguments, $request, $headers); $this->createResponse(MessageTypes::RESPONSE, $result, $response, $request); } catch (\Exception $e) { $this->createResponse(MessageTypes::ERROR, $e, $response, $request); } $this->transport->sendResponse($response); break; case MethodTypes::ONE_WAY: $this->createResponse(MessageTypes::ONE_WAY_ACK, null, $response, $request); $this->transport->sendResponse($response); $method->call($arguments, $request); break; case MethodTypes::PUSH: $self = $this; $ackCalled = false; $result = null; $transport = $this->transport; // hack for php 5.3 which makes "createResponse" accessible from closure $createResponseMethod = new \ReflectionMethod($this, 'createResponse'); $createResponseMethod->setAccessible(true); $ack = function ($result = null) use($self, &$ackCalled, $response, $request, $transport, $createResponseMethod) { if ($ackCalled) { return; } $ackCalled = true; $createResponseMethod->invoke($self, MessageTypes::PUSH_ACK, $result, $response, $request); $transport->sendResponse($response); }; try { $result = $method->call($arguments, $request, $headers, $ack); $ack($result); } catch (\Exception $e) { // we cannot send error message when ack was called before that moment if ($ackCalled) { throw $e; } $ackCalled = true; $this->createResponse(MessageTypes::ERROR, $e, $response, $request); $self->transport->sendResponse($response); } break; } }
/** * {@inheritDoc} */ public function receiveResponse() { try { $result = $this->socket->recvMulti(); } catch (\ZMQSocketException $e) { throw new TransportException('Cannot receive response', 0, $e); } if ($result === false) { throw new TimeoutException('Timeout (' . $this->getTimeout() . 's) reached'); } if (!isset($result[0])) { throw new FormatException('Invalid response - no response type', $result); } if (!isset($result[1])) { throw new FormatException('Invalid response - no headers', $result); } $response = new Response($result[0]); $response->setHeaders(new Headers(Parser::parseHeaders($result[1]))); if (!MessageTypes::isResponseTypeWithResult($response->getType())) { return $response; } if (!isset($result[2])) { throw new FormatException('Invalid response - no response body', $result); } return $response->setResultBody($result[2]); }