/** {@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;
 }
Пример #2
0
 /**
  * Fire timeout event and processes user response
  *
  * @param RequestDescriptor $descriptor
  *
  * @return bool True if we may do one more attempt, false otherwise
  */
 public function handleTimeoutOnDescriptor(RequestDescriptor $descriptor)
 {
     $meta = $descriptor->getMetadata();
     $event = new TimeoutEvent($this->executor, $descriptor->getSocket(), $meta[RequestExecutorInterface::META_USER_CONTEXT], $meta[RequestExecutorInterface::META_CONNECTION_FINISH_TIME] !== null && !$descriptor->getSocket() instanceof ServerSocket ? TimeoutEvent::DURING_IO : TimeoutEvent::DURING_CONNECTION);
     try {
         $this->callSocketSubscribers($descriptor, $event);
         $result = $event->isNextAttemptEnabled();
     } catch (SocketException $e) {
         $this->callExceptionSubscribers($descriptor, $e);
         $result = false;
     }
     if ($result) {
         $this->updateMetadataForAttempt($descriptor, $event->when());
     }
     return $result;
 }
Пример #3
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();
     }
 }
Пример #4
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);
 }
Пример #5
0
 /**
  * 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();
 }
Пример #6
0
 /**
  * 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);
 }
Пример #7
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);
 }
Пример #8
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;
 }
Пример #9
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);
 }
Пример #10
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);
     }
 }
Пример #11
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;
 }