Beispiel #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);
        });
}
Beispiel #2
0
 static void send(const char *msg, int len, const SocketClient::SharedPtr &socket)
 {
     static const unsigned char *header = reinterpret_cast<const unsigned char*>("data:");
     static const unsigned char *crlf = reinterpret_cast<const unsigned char*>("\r\n");
     socket->write(header, 5);
     socket->write(reinterpret_cast<const unsigned char *>(msg), len);
     socket->write(crlf, 2);
 }
Beispiel #3
0
Connection::Connection(const SocketClient::SharedPtr &client)
    : mSocketClient(client), mPendingRead(0), mPendingWrite(0), mTimeoutTimer(0), mFinishStatus(0),
      mSilent(false), mIsConnected(true), mWarned(false)
{
    assert(client->isConnected());
    mSocketClient->disconnected().connect(std::bind(&Connection::onClientDisconnected, this, std::placeholders::_1));
    mSocketClient->readyRead().connect(std::bind(&Connection::onDataAvailable, this, std::placeholders::_1, std::placeholders::_2));
    mSocketClient->bytesWritten().connect(std::bind(&Connection::onDataWritten, this, std::placeholders::_1, std::placeholders::_2));
    mSocketClient->error().connect(std::bind(&Connection::onSocketError, this, std::placeholders::_1, std::placeholders::_2));
    EventLoop::eventLoop()->callLater(std::bind(&Connection::initConnection, this));
}
Beispiel #4
0
void Connection::connect(const SocketClient::SharedPtr &client)
{
    assert(!mSocketClient);
    mSocketClient = client;
    mIsConnected = true;
    assert(client->isConnected());
    mSocketClient->disconnected().connect(std::bind(&Connection::onClientDisconnected, this, std::placeholders::_1));
    mSocketClient->readyRead().connect(std::bind(&Connection::onDataAvailable, this, std::placeholders::_1, std::placeholders::_2));
    mSocketClient->bytesWritten().connect(std::bind(&Connection::onDataWritten, this, std::placeholders::_1, std::placeholders::_2));
    mSocketClient->error().connect(std::bind(&Connection::onSocketError, this, std::placeholders::_1, std::placeholders::_2));
    mCheckTimer = EventLoop::eventLoop()->registerTimer([this](int) { checkData(); }, 0, Timer::SingleShot);
}
Beispiel #5
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();
    }
}
Beispiel #6
0
void Connection::connect(const SocketClient::SharedPtr &client)
{
    mSocketClient = client;
    mIsConnected = true;
    assert(client->isConnected());
    auto that = shared_from_this();
    mSocketClient->disconnected().connect(std::bind(&Connection::onClientDisconnected, that, std::placeholders::_1));
    mSocketClient->readyRead().connect(std::bind(&Connection::onDataAvailable, that, std::placeholders::_1, std::placeholders::_2));
    mSocketClient->bytesWritten().connect(std::bind(&Connection::onDataWritten, that, std::placeholders::_1, std::placeholders::_2));
    mSocketClient->error().connect(std::bind(&Connection::onSocketError, that, std::placeholders::_1, std::placeholders::_2));
    send(ConnectMessage());
    std::weak_ptr<Connection> weak = that;
    EventLoop::eventLoop()->callLater([weak]() {
            if (auto strong = weak.lock())
                strong->checkData();
        });
}