#ifndef RTC_IMPL_WS_TRANSPORT_H
#define RTC_IMPL_WS_TRANSPORT_H
#include "common.hpp"
#include "transport.hpp"
#include "wshandshake.hpp"
#if RTC_ENABLE_WEBSOCKET
namespace rtc::impl {
class TcpTransport;
class TlsTransport;
class WsTransport final : public Transport {
public:
WsTransport(variant<shared_ptr<TcpTransport>, shared_ptr<TlsTransport>> lower,
shared_ptr<WsHandshake> handshake, message_callback recvCallback,
state_callback stateCallback);
~WsTransport();
void start() override;
bool stop() override;
bool send(message_ptr message) override;
void incoming(message_ptr message) override;
void close();
bool isClient() const { return mIsClient; }
private:
enum Opcode : uint8_t {
CONTINUATION = 0,
TEXT_FRAME = 1,
BINARY_FRAME = 2,
CLOSE = 8,
PING = 9,
PONG = 10,
};
struct Frame {
Opcode opcode = BINARY_FRAME;
byte *payload = nullptr;
size_t length = 0;
bool fin = true;
bool mask = true;
};
bool sendHttpRequest();
bool sendHttpError(int code);
bool sendHttpResponse();
size_t readFrame(byte *buffer, size_t size, Frame &frame);
void recvFrame(const Frame &frame);
bool sendFrame(const Frame &frame);
const shared_ptr<WsHandshake> mHandshake;
const bool mIsClient;
binary mBuffer;
binary mPartial;
Opcode mPartialOpcode;
std::mutex mSendMutex;
};
}
#endif
#endif