Пример #1
0
CWebSocketClient::CWebSocketClient(QUrl url, QObject *parent)
	: m_url(url), QObject(parent)
{
	//m_url = QUrl(QStringLiteral("ws://localhost:1234"));

	connect(&m_webSocket, &QWebSocket::connected,		this, &CWebSocketClient::onConnected);
	connect(&m_webSocket, &QWebSocket::disconnected,	this, &CWebSocketClient::serverDisconnected);

	//Client tries to connect every 5s
	connection_Timer = new QTimer(this);
	connection_Timer->setInterval(5000);

	connect(connection_Timer,	SIGNAL(timeout()),		this,				SLOT(onConnectionTimeout()));
	connect(&m_webSocket,		SIGNAL(disconnected()),	this,				SLOT(resetSocket()));

	connect(&m_webSocket,		SIGNAL(connected()),	connection_Timer,	SLOT(stop()));
	connect(&m_webSocket,		SIGNAL(disconnected()),	connection_Timer,	SLOT(start()));

	connection_Timer->start();
}
Пример #2
0
void IoConnection::writeSocket()
{
    switch (_wsock_state)
    {
        case SOCKET_CONNECTING:
        {
            int error = -1;
            socklen_t len = sizeof(error);
            getsockopt(_socket, SOL_SOCKET, SO_ERROR, &error, &len);
            if (error != 0)
            {
                LOG(INFO) << "connecting error\n";

                resetSocket();
                return;
            }

            _wsock_state = SOCKET_DATA_WRITE;
        }
        case SOCKET_DATA_WRITE:
        {
            if (_current_push == 0)
            {
                _current_push = getPushData();
                if (_current_push == 0)
                {
                    _setWrite(false);
                    _setRead(true);
                    return;
                }
            }

            if (_current_push->_msg->_close_conn)
            {
                //need closed by upstream logic
                resetSocket();
                return;
            }

            char* wbuf = _current_push->_wbuf + _current_push->_wpos;
            int left = _current_push->_wsize - _current_push->_wpos;

            while (left > 0)
            {
                int32_t put = ::send(_socket, wbuf, left, MSG_NOSIGNAL);
                if (put > 0)
                {
                    _current_push->_wpos += put;
                    left -= put;
                    break;
                }
                else if (put == -1)
                {
                    switch (errno)
                    {
                        case EINTR:
                            continue;
                        case EAGAIN:
                            return;
                        default:
                            resetSocket();
                            return;
                    }
                }
                else
                {
                    return;
                }
            }

            if (left == 0)
            {
                //TODO
                //we send msg to wan,but the peer may not receive
                //we just drop the msg, in the future may be use ack
                destroyMsgData(_current_push);
                _current_push = getPushData();
                if (_current_push == 0)
                {
                    _setWrite(false);
                    _setRead(true);
                    return;
                }
            }

            break;
        }
        default:
        {
            LOG(INFO) << "write state(" << _wsock_state << ") error\n";
            resetSocket();
            return;
        }
    }
}
Пример #3
0
void IoConnection::readSocket()
{
    switch (_rsock_state)
    {
        case SOCKET_RECV_FRAMING:
        {
            while (true)
            {
                int fetch = ::recv(_socket, _rbuf+_rpos, _rsize-_rpos, 0);
                if (fetch > 0)
                {
                    _rpos += fetch;
                }
                else if (fetch == 0)
                {
                    //we think client closed
                    closeSocket();
                    return;
                }
                else
                {
                    switch (errno)
                    {
                        case EAGAIN:
                            break;
                        case EINTR:
                            continue;
                        default:
                            //any other error, reset conn
                            resetSocket();
                            break;
                        /*
                        default:
                        {
                            //the latest write may cause error: ETIMEDOUT,EHOSTUNREACH,ENETUNREACH
                            if (_rpos > 0 || errno == ETIMEDOUT || errno == EHOSTUNREACH || errno == ENETUNREACH)
                            {
                                //we have received some data,so we think client abnormally closed
                                //resetSocket();
                                //we should keep TIME_WAIT
                                closeSocket();
                            }
                            else
                            {
                                //the latest write may cause error: ECONNRESET, but we can't distinguish this situation
                                //we think client normally close
                                closeSocket();
                            }
                            return;
                        }
                        */
                    }
                }

                break;
            }

            //we have some data arrived
            if (_rpos < (int)sizeof(int))
            {
                //TODO,if we reset timeout
                return;
            }

            _frame_size = ntohl(*((unsigned int*)_rbuf)) + sizeof(int);
            if (_frame_size > FRAME_MAX_SIZE)
            {
                //frame too large, close
                resetSocket();
                return;
            }

            if ((int)_frame_size > _rsize)
            {
                int new_size = _frame_size + READ_BUFFER_INCREAMENT_SIZE;
                if (new_size > FRAME_MAX_SIZE)
                    new_size = FRAME_MAX_SIZE;
                char* new_buffer = new (std::nothrow) char [new_size];
                if (new_buffer == 0)
                {
                    //memory error,reset
                    resetSocket();
                    return;
                }

                memcpy(new_buffer, _rbuf, _rpos);
                delete [] _rbuf;

                _rbuf = new_buffer;
                _rsize = new_size;
            }

            _rsock_state = SOCKET_DATA_RECV;
        }
        case SOCKET_DATA_RECV:
        {
            int left = _frame_size-_rpos;
            while (left > 0)
            {
                int fetch = ::recv(_socket, _rbuf+_rpos, left, 0);
                if (fetch > 0)
                {
                    _rpos += fetch;
                    break;
                }
                else if (fetch == 0)
                {
                    closeSocket();
                    return;
                }
                else
                {
                    switch (errno)
                    {
                        case EINTR:
                            continue;
                        case EAGAIN:
                            return;
                        default:
                            resetSocket();
                            return;
                    }
                }
            }

            if (_rpos == (int)_frame_size)
            {
                int ret = this->whenReceivedFrame(_rbuf, _frame_size);
                if (ret == -1)
                {
                    //internal error, close
                    resetSocket();
                    return;
                }

                //接着读新请求
                _rpos = 0;
                _rsock_state = SOCKET_RECV_FRAMING;
            }
            else if (_rpos > (int)_frame_size)
            {
                char* b = _rbuf;
                int frame_size = _frame_size;
                int len = _rpos;
                int ret;
                while (len >= frame_size)
                {
                    ret = this->whenReceivedFrame(b, frame_size);
                    if (ret == -1)
                    {
                        //internal error, close
                        resetSocket();
                        return;
                    }

                    b += frame_size;
                    len -= frame_size;
                    if (len >= (int)sizeof(int))
                    {
                        frame_size = ntohl(*((unsigned int*)b)) + sizeof(int);
                    }
                    else
                    {
                        break;
                    }
                }

                memcpy(_rbuf, b, len);
                _rpos = len;
                _rsock_state = SOCKET_RECV_FRAMING;
            }

            break;
        }
        default:
        {
            LOG(ERROR) << "socket state error, abort\n";
            abort();
        }
    }
}