public function connect()
    {
        if ($this->state !== ClientStateEnum::NOT_CONNECTED) {
            throw new ClientException("Client already connected/connecting.");
        }

        try {
            $this->state = ClientStateEnum::CONNECTING;

            $this->writer->appendProtocolHeader($this->writeBuffer);
            $this->flushWriteBuffer();
            $this->authResponse($this->awaitConnectionStart());
            $tune = $this->awaitConnectionTune();
            $this->connectionTuneOk($tune->channelMax, $tune->frameMax, $this->options["heartbeat"]); // FIXME: options heartbeat
            $this->frameMax = $tune->frameMax;
            if ($tune->channelMax > 0) {
                $this->channelMax = $tune->channelMax;
            }
            $this->connectionOpen($this->options["vhost"]);

            $this->state = ClientStateEnum::CONNECTED;

            return $this;

        } catch (\Exception $e) {
            $this->state = ClientStateEnum::ERROR;
            throw $e;
        }
    }