public function run()
    {
        $this->connect();

        // tell server we want to listen
        $this->connection->writeText('{ "action" : "listen" }');

        while (!$this->moribund) {

            $read = array($this->connection->getSocket()->getRawSocket());

            // Suppressing warnings for stream_select() because it will raise
            // a warning if interrupted by a signal.
            $result = @stream_select(
                $read,
                $write = null,
                $except = null,
                null
            );

            if ($result === false || $result < 1) {
                continue;
            }

            $moribund = false;

            // check if server closed connection
            $bytes = $this->connection->getSocket()->peek(1);

            if (mb_strlen($bytes, '8bit') === 0) {
                $this->log(
                    'server closed connection.' . PHP_EOL,
                    Net_Notifier_Logger::VERBOSITY_CLIENT
                );

                $moribund = true;
            }

            try {

                if ($this->connection->read(Net_Notifier_Client::READ_BUFFER_LENGTH)) {

                    if ($this->connection->getState() < Net_Notifier_WebSocket_Connection::STATE_CLOSING) {

                        $messages = $this->connection->getTextMessages();
                        foreach ($messages as $message) {
                            if (mb_strlen($message, '8bit') > 0) {
                                $this->log(
                                    sprintf(
                                        'received message: "%s"' . PHP_EOL,
                                        $message
                                    ),
                                    Net_Notifier_Logger::VERBOSITY_MESSAGES
                                );
                                $this->handleMessage($message);
                            }
                        }
                    }

                } else {

                    $this->log(
                        'got a message chunk from server' . PHP_EOL,
                        Net_Notifier_Logger::VERBOSITY_CLIENT
                    );

                }

            } catch (Net_Notifier_WebSocket_HandshakeFailureException $e) {
                $this->log(
                    sprintf(
                        'failed server handshake: %s' . PHP_EOL,
                        $e->getMessage()
                    ),
                    Net_Notifier_Logger::VERBOSITY_CLIENT
                );
            }

            if ($moribund) {
                $this->connection->close();
                break;
            }

        }

        if ($this->connection->getState() < Net_Notifier_WebSocket_Connection::STATE_CLOSING) {
            $this->disconnect();
        }
    }