Example #1
0
 /**
  * @param resource $socket An open socket client resource
  */
 public function __construct($socket)
 {
     \stream_set_blocking($socket, false);
     $this->state = $state = new \StdClass();
     $readWatcherId = amp\onReadable($socket, static function ($wid, $socket) use($state) {
         $data = @\fread($socket, 8192);
         if ($data != "") {
             $state->bytesRead += \strlen($data);
             $op = \reset($state->readOperations);
             $op->buffer .= $data;
             Client::onRead($state);
         } else {
             Client::onEmptyRead($state);
         }
     }, $options = ["enable" => false]);
     $writeWatcherId = amp\onWritable($socket, static function ($wid, $socket) use($state) {
         $op = \current($state->writeOperations);
         if ($bytes = @\fwrite($socket, $op->buffer)) {
             $state->bytesSent += $bytes;
             Client::onWrite($state, $op, $bytes);
         } else {
             Client::onEmptyWrite($state);
         }
     }, $options = ["enable" => false]);
     $state->readWatcherId = $readWatcherId;
     $state->writeWatcherId = $writeWatcherId;
     $state->socket = $socket;
     $state->isDead = false;
     $state->localName = \stream_socket_get_name($socket, $wantPeer = false);
     $state->remoteName = \stream_socket_get_name($socket, $wantPeer = true);
     $state->readOperations = [];
     $state->writeOperations = [];
     $state->bytesRead = 0;
     $state->bytesSent = 0;
     // We avoid instantiating a closure every time a socket read/write completes
     // without exposing a method in the public API this way ... it may look hacky
     // but it's important for performance.
     if (empty(self::$succeeder)) {
         $callable = (new \ReflectionClass($this))->getMethod("succeed")->getClosure($this);
         self::$succeeder = $callable;
     }
 }