host = $host; $this->port = $port; $this->setRecvTimeoutSec($recvTimeoutSec); $this->setRecvTimeoutUsec($recvTimeoutUsec); $this->setSendTimeoutSec($sendTimeoutSec); $this->setSendTimeoutUsec($sendTimeoutUsec); } /** * @param float $sendTimeoutSec */ public function setSendTimeoutSec($sendTimeoutSec) { $this->sendTimeoutSec = $sendTimeoutSec; } /** * @param float $sendTimeoutUsec */ public function setSendTimeoutUsec($sendTimeoutUsec) { $this->sendTimeoutUsec = $sendTimeoutUsec; } /** * @param float $recvTimeoutSec */ public function setRecvTimeoutSec($recvTimeoutSec) { $this->recvTimeoutSec = $recvTimeoutSec; } /** * @param float $recvTimeoutUsec */ public function setRecvTimeoutUsec($recvTimeoutUsec) { $this->recvTimeoutUsec = $recvTimeoutUsec; } /** * @param int $number */ public function setMaxWriteAttempts($number) { $this->maxWriteAttempts = $number; } // }}} // {{{ public function connect() /** * Connects the socket * * @access public * @return void */ public function connect() { if (!$this->isSocketDead()) { return; } if (empty($this->host)) { throw new \Kafka\Exception('Cannot open null host.'); } if ($this->port <= 0) { throw new \Kafka\Exception('Cannot open without port.'); } $this->stream = new \Swoole\Coroutine\Socket(AF_INET, SOCK_STREAM);; if (!$this->stream->connect( $this->host, $this->port, $this->sendTimeoutSec + ($this->sendTimeoutUsec / 1000000) )) { $error = 'Could not connect to ' . $this->host . ':' . $this->port . ' (' . $this->stream->errMsg . ' [' . $this->stream->errCode . '])'; throw new \Kafka\Exception($error); } // stream_set_blocking($this->stream->getpeername(), 0); // stream_set_read_buffer($this->stream, 0); // $this->readWatcher = \Amp\onReadable($this->stream, function () { // do { // try { // if (!$this->isSocketDead($this->stream)) { // $newData = $this->stream->recv(self::READ_MAX_LEN); // } else { // $this->reconnect(); // return; // } // if ($newData) { // $this->read($newData); // } // } catch (\Exception $exception) { // var_dump($exception->getMessage()); // } // } while ($newData); // }); // // $this->writeWatcher = \Amp\onWritable($this->stream, function () { // $this->write(); // }, array('enable' => false)); // <-- let's initialize the watcher as "disabled" } // }}} // {{{ public function reconnect() /** * reconnect the socket * * @access public * @return void */ public function reconnect() { $this->close(); $this->connect(); } // }}} // {{{ public function getSocket() /** * get the socket * * @access public * @return void */ public function getSocket() { return $this->stream; } // }}} // {{{ public function SetOnReadable() public $onReadable; /** * set on readable callback function * * @access public * @return void */ public function SetOnReadable(\Closure $read) { $this->onReadable = $read; } // }}} // {{{ public function close() /** * close the socket * * @access public * @return void */ public function close() { \Amp\cancel($this->readWatcher); \Amp\cancel($this->writeWatcher); $this->stream->close(); $this->readBuffer = ''; $this->writeBuffer = ''; $this->readNeedLength = 0; } /** * checks if the socket is a valid resource * * @access public * @return boolean */ public function isResource() { return is_resource($this->stream); } // }}} // {{{ public function read() /** * Read from the socket at most $len bytes. * * This method will not wait for all the requested data, it will return as * soon as any data is received. * * @param integer $len Maximum number of bytes to read. * @param boolean $verifyExactLength Throw an exception if the number of read bytes is less than $len * * @return string Binary data * @throws \Kafka\Exception\SocketEOF */ public function read($data) { $this->readBuffer .= $data; do { if ($this->readNeedLength == 0) { // response start if (strlen($this->readBuffer) < 4) { return; } $dataLen = \Kafka\Protocol\Protocol::unpack(\Kafka\Protocol\Protocol::BIT_B32, substr($this->readBuffer, 0, 4)); $this->readNeedLength = $dataLen; $this->readBuffer = substr($this->readBuffer, 4); } if (strlen($this->readBuffer) < $this->readNeedLength) { return; } $data = substr($this->readBuffer, 0, $this->readNeedLength); $this->readBuffer = substr($this->readBuffer, $this->readNeedLength); $this->readNeedLength = 0; call_user_func($this->onReadable, $data, (int)$this->stream); } while (strlen($this->readBuffer)); } // }}} // {{{ public function write() /** * Write to the socket. * * @param string $buf The data to write * * @return integer * @throws \Kafka\Exception\SocketEOF */ public function write($data = null) { if ($data != null) { $this->writeBuffer .= $data; } $bytesToWrite = strlen($this->writeBuffer); $bytesWritten = $this->stream->send($this->writeBuffer); // if ($bytesToWrite === $bytesWritten) { // \Amp\disable($this->writeWatcher); // } elseif ($bytesWritten >= 0) { // \Amp\enable($this->writeWatcher); // } $this->writeBuffer = substr($this->writeBuffer, $bytesWritten); } // }}} // {{{ protected function isSocketDead() /** * check the stream is close * * @return bool */ protected function isSocketDead() { if (!($this->stream instanceof \Swoole\Coroutine\Socket)) { return true; } return $this->stream->checkLiveness(); } // }}} // }}} }