Example #1
0
WebSocket::WebSocket(const SocketClient::SharedPtr& client)
    : mClient(client)
{
    wslay_event_callbacks callbacks = {
        wslayRecvCallback,
        wslaySendCallback,
        0, // genmask_callback
        0, // on_frame_recv_start_callback
        0, // on_frame_recv_callback
        0, // on_frame_recv_end_callback
        wslayOnMsgRecvCallback
    };
    wslay_event_context_server_init(&mCtx, &callbacks, this);

    client->readyRead().connect([this](const SocketClient::SharedPtr& client, Buffer&& buf) {
            if (buf.isEmpty())
                return;
            mBuffers.push_back(std::move(buf));
            if (wslay_event_recv(mCtx) < 0) {
                // close socket
                client->close();
                mClient.reset();
                mError(this);
            }
        });
    client->disconnected().connect([this](const SocketClient::SharedPtr& client) {
            mClient.reset();
            mDisconnected(this);
        });
}
Example #2
0
void Connection::onDataAvailable(const SocketClient::SharedPtr &client, Buffer&& buf)
{
    auto that = shared_from_this();
    while (true) {
        if (!buf.isEmpty())
            mBuffers.push(std::forward<Buffer>(buf));

        unsigned int available = mBuffers.size();
        if (!available)
            break;
        if (!mPendingRead) {
            if (available < static_cast<int>(sizeof(uint32_t)))
                break;
            union {
                unsigned char b[sizeof(uint32_t)];
                int pending;
            };
            const int read = mBuffers.read(b, 4);
            assert(read == 4);
            mPendingRead = pending;
            assert(mPendingRead > 0);
            available -= read;
        }
        assert(mPendingRead >= 0);
        if (available < static_cast<unsigned int>(mPendingRead))
            break;

        StackBuffer<1024 * 16> buffer(mPendingRead);
        const int read = mBuffers.read(buffer.buffer(), mPendingRead);
        assert(read == mPendingRead);
        mPendingRead = 0;
        Message::MessageError error;
        std::shared_ptr<Message> message = Message::create(mVersion, buffer, read, &error);
        if (message) {
            if (message->messageId() == FinishMessage::MessageId) {
                mFinishStatus = std::static_pointer_cast<FinishMessage>(message)->status();
                mFinished(that, mFinishStatus);
            } else {
                newMessage()(message, that);
            }
        } else if (mErrorHandler) {
            mErrorHandler(client, std::move(error));
        } else {
            ::error() << "Unable to create message from data" << error.type << error.text << read;
        }
        if (!message)
            client->close();
    }
}