示例#1
0
 /** {@inheritdoc} */
 protected function handleOperation(RequestDescriptor $descriptor, RequestExecutorInterface $executor, EventHandlerInterface $eventHandler)
 {
     $operation = $descriptor->getOperation();
     $socket = $descriptor->getSocket();
     $meta = $executor->socketBag()->getSocketMetaData($socket);
     $context = $meta[RequestExecutorInterface::META_USER_CONTEXT];
     try {
         /** @var ReadOperation $operation */
         $response = $socket->read($operation->getFramePicker());
         switch (true) {
             case $response instanceof PartialFrame:
                 return $operation;
             case $response instanceof AcceptedFrame:
                 $event = new AcceptEvent($executor, $socket, $context, $response->getClientSocket(), $response->getRemoteAddress());
                 $eventHandler->invokeEvent($event);
                 return new ReadOperation();
             default:
                 $event = new ReadEvent($executor, $socket, $context, $response, false);
                 $eventHandler->invokeEvent($event);
                 return $event->getNextOperation();
         }
     } catch (AcceptException $e) {
         return new ReadOperation();
     }
 }
 /**
  * Set start or finish time in metadata of the socket
  *
  * @param RequestDescriptor $requestDescriptor Socket meta data
  * @param string            $key Metadata key to set
  *
  * @return void
  * @throws \InvalidArgumentException
  */
 protected function setSocketOperationTime(RequestDescriptor $requestDescriptor, $key)
 {
     $meta = $requestDescriptor->getMetadata();
     $table = [RequestExecutorInterface::META_CONNECTION_START_TIME => $meta[RequestExecutorInterface::META_CONNECTION_START_TIME] === null, RequestExecutorInterface::META_CONNECTION_FINISH_TIME => $meta[RequestExecutorInterface::META_CONNECTION_FINISH_TIME] === null, RequestExecutorInterface::META_LAST_IO_START_TIME => $meta[RequestExecutorInterface::META_CONNECTION_FINISH_TIME] !== null];
     if (isset($table[$key]) && $table[$key]) {
         $requestDescriptor->setMetadata($key, microtime(true));
     }
 }
示例#3
0
 /**
  * Check whether socket waiting is finished
  *
  * @param RequestDescriptor $descriptor Request descriptor to test
  *
  * @return bool True if delay is complete, false otherwise
  */
 private function checkDelayIsFinished(RequestDescriptor $descriptor)
 {
     /** @var DelayedOperation $socketOperation */
     $socketOperation = $descriptor->getOperation();
     $arguments = $socketOperation->getArguments();
     array_unshift($arguments, $descriptor->getSocket(), $this->executor);
     return !call_user_func_array($socketOperation->getCallable(), $arguments);
 }
示例#4
0
 /**
  * Update data inside descriptor to make one more attempt
  *
  * @param RequestDescriptor $descriptor Operation descriptor
  * @param string            $when When Timeout occurerd, one of TimeoutEvent::DURING_* consts
  *
  * @return void
  */
 private function updateMetadataForAttempt(RequestDescriptor $descriptor, $when)
 {
     switch ($when) {
         case TimeoutEvent::DURING_IO:
             $descriptor->setMetadata(RequestExecutorInterface::META_LAST_IO_START_TIME, null);
             break;
         case TimeoutEvent::DURING_CONNECTION:
             $descriptor->setRunning(false);
             $descriptor->setMetadata([RequestExecutorInterface::META_LAST_IO_START_TIME => null, RequestExecutorInterface::META_CONNECTION_START_TIME => null, RequestExecutorInterface::META_CONNECTION_FINISH_TIME => null]);
             break;
     }
 }
 /**
  * Handle OOB data
  *
  * @param RequestDescriptor        $descriptor Request descriptor
  * @param RequestExecutorInterface $executor Executor, processing operation
  * @param EventHandlerInterface    $eventHandler Event handler for this operation
  *
  * @return OperationInterface|null Operation to return to user or null to continue normal processing
  */
 private function handleOobData(RequestDescriptor $descriptor, RequestExecutorInterface $executor, EventHandlerInterface $eventHandler)
 {
     if (!$descriptor->hasState(RequestDescriptor::RDS_OOB)) {
         return null;
     }
     $descriptor->clearState(RequestDescriptor::RDS_OOB);
     $picker = new RawFramePicker();
     $socket = $descriptor->getSocket();
     $meta = $descriptor->getMetadata();
     $frame = $socket->read($picker, true);
     $event = new ReadEvent($executor, $socket, $meta[RequestExecutorInterface::META_USER_CONTEXT], $frame, true);
     $eventHandler->invokeEvent($event);
     return $event->getNextOperation();
 }
 /** {@inheritdoc} */
 protected function handleOperation(RequestDescriptor $descriptor, RequestExecutorInterface $executor, EventHandlerInterface $eventHandler)
 {
     $operation = $descriptor->getOperation();
     $socket = $descriptor->getSocket();
     /** @var SslHandshakeOperation $operation */
     $resource = $descriptor->getSocket()->getStreamResource();
     $result = stream_socket_enable_crypto($resource, true, $operation->getCipher());
     if ($result === true) {
         return $operation->getNextOperation();
     } elseif ($result === false) {
         throw new SslHandshakeException($socket, 'SSL handshake failed.');
     }
     return $operation;
 }
 /**
  * Disconnects given socket descriptor
  *
  * @param RequestDescriptor $descriptor Socket descriptor
  *
  * @return void
  */
 public function disconnect(RequestDescriptor $descriptor)
 {
     $meta = $descriptor->getMetadata();
     $socket = $descriptor->getSocket();
     $descriptor->setMetadata(RequestExecutorInterface::META_REQUEST_COMPLETE, true);
     try {
         $socket->close();
         if ($meta[RequestExecutorInterface::META_CONNECTION_FINISH_TIME] !== null) {
             $this->callSocketSubscribers($descriptor, $this->createEvent($descriptor, EventType::DISCONNECTED));
         }
     } catch (SocketException $e) {
         $this->callExceptionSubscribers($descriptor, $e);
     }
     $this->callSocketSubscribers($descriptor, $this->createEvent($descriptor, EventType::FINALIZE));
     $this->removeOperationsFromSelector($descriptor);
 }
示例#8
0
 /** {@inheritdoc} */
 protected function handleOperation(RequestDescriptor $descriptor, RequestExecutorInterface $executor, EventHandlerInterface $eventHandler)
 {
     $operation = $descriptor->getOperation();
     $socket = $descriptor->getSocket();
     /** @var WriteOperation $operation */
     $fireEvent = !$operation instanceof InProgressWriteOperation;
     if ($fireEvent) {
         $meta = $executor->socketBag()->getSocketMetaData($socket);
         $event = new WriteEvent($operation, $executor, $socket, $meta[RequestExecutorInterface::META_USER_CONTEXT]);
         $eventHandler->invokeEvent($event);
         $nextOperation = $event->getNextOperation();
     } else {
         $nextOperation = $operation;
     }
     return $this->writeDataToSocket($operation, $socket, $nextOperation);
 }
 /**
  * Resolves timeout for setting up event
  *
  * @param RequestDescriptor $descriptor Descriptor object
  *
  * @return int
  */
 private function resolveTimeout(RequestDescriptor $descriptor)
 {
     $meta = $descriptor->getMetadata();
     $key = spl_object_hash($descriptor);
     $result = $meta[RequestExecutorInterface::META_IO_TIMEOUT];
     if (!isset($this->connectedDescriptors[$key])) {
         $result = $meta[RequestExecutorInterface::META_CONNECTION_TIMEOUT];
         $this->connectedDescriptors[$key] = true;
     }
     return $result;
 }
示例#10
0
 /**
  * Start connecting process
  *
  * @param RequestDescriptor $descriptor Socket operation data
  *
  * @return bool True if successfully connected, false otherwise
  */
 private function connectSocket(RequestDescriptor $descriptor)
 {
     $descriptor->initialize();
     $socket = $descriptor->getSocket();
     $event = $this->createEvent($descriptor, EventType::INITIALIZE);
     try {
         $this->callSocketSubscribers($descriptor, $event);
         $this->setSocketOperationTime($descriptor, RequestExecutorInterface::META_CONNECTION_START_TIME);
         $meta = $descriptor->getMetadata();
         $socket->open($meta[RequestExecutorInterface::META_ADDRESS], $this->getStreamContextFromMetaData($meta));
         $descriptor->setRunning(true);
         $result = true;
     } catch (SocketException $e) {
         $descriptor->setMetadata(RequestExecutorInterface::META_REQUEST_COMPLETE, true);
         $this->callExceptionSubscribers($descriptor, $e);
         $result = false;
     }
     return $result;
 }
示例#11
0
 /**
  * Notify handlers about exception
  *
  * @param RequestDescriptor $requestDescriptor Socket operation object
  * @param SocketException   $exception Thrown exception
  *
  * @return void
  */
 public function callExceptionSubscribers(RequestDescriptor $requestDescriptor, SocketException $exception)
 {
     if ($exception instanceof StopSocketOperationException) {
         return;
     }
     $meta = $requestDescriptor->getMetadata();
     $exceptionEvent = new SocketExceptionEvent($exception, $this->executor, $requestDescriptor->getSocket(), $meta[RequestExecutorInterface::META_USER_CONTEXT]);
     $this->callSocketSubscribers($requestDescriptor, $exceptionEvent);
 }
示例#12
0
 /**
  * Set connection finish time and fire socket if it was not connected
  *
  * @param RequestDescriptor $requestDescriptor
  *
  * @return bool True, if there was no error, false if operation should be stopped
  */
 private function setConnectionFinishTime(RequestDescriptor $requestDescriptor)
 {
     $meta = $requestDescriptor->getMetadata();
     $wasConnected = $meta[RequestExecutorInterface::META_CONNECTION_FINISH_TIME] !== null;
     $this->setSocketOperationTime($requestDescriptor, RequestExecutorInterface::META_CONNECTION_FINISH_TIME);
     if (!$wasConnected) {
         $event = $this->createEvent($requestDescriptor, EventType::CONNECTED);
         try {
             $this->callSocketSubscribers($requestDescriptor, $event);
         } catch (SocketException $e) {
             $this->callExceptionSubscribers($requestDescriptor, $e);
             return false;
         }
     }
     return true;
 }
示例#13
0
 /**
  * Notify client about unhandled data in socket
  *
  * @param RequestDescriptor $descriptor Socket operation descriptor
  * @param int               $attempt Current attempt number from 1
  * @param int               $totalAttempts Total attempts
  *
  * @return void
  */
 private function notifyDataAlert(RequestDescriptor $descriptor, $attempt, $totalAttempts)
 {
     $socket = $descriptor->getSocket();
     $meta = $this->executor->socketBag()->getSocketMetaData($socket);
     $event = new DataAlertEvent($this->executor, $socket, $meta[RequestExecutorInterface::META_USER_CONTEXT], $attempt, $totalAttempts);
     $this->callSocketSubscribers($descriptor, $event);
     $operation = $event->getNextOperation();
     if ($operation) {
         $descriptor->setOperation($operation);
     }
 }
 /**
  * Check whether given descriptor is active
  *
  * @param RequestDescriptor $descriptor
  *
  * @return bool
  */
 private function isDescriptorActive(RequestDescriptor $descriptor)
 {
     $meta = $descriptor->getMetadata();
     return !$meta[RequestExecutorInterface::META_REQUEST_COMPLETE] && $descriptor->isRunning() && !$descriptor->isPostponed();
 }
示例#15
0
 /**
  * Create simple event
  *
  * @param RequestDescriptor $operation Operation item
  * @param string            $eventName Event name for object
  *
  * @return Event
  */
 protected function createEvent(RequestDescriptor $operation, $eventName)
 {
     $meta = $operation->getMetadata();
     return new Event($this->executor, $operation->getSocket(), $meta[RequestExecutorInterface::META_USER_CONTEXT], $eventName);
 }
 /** {@inheritdoc} */
 public function isSatisfiedBy(RequestDescriptor $requestDescriptor)
 {
     return $requestDescriptor->getSocket() instanceof UdpClientSocket && $requestDescriptor->getOperation() instanceof ReadOperation;
 }