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); }); }
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); }
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)); }
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); }
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(); } }
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(); }); }