79 lines
1.9 KiB
C++
79 lines
1.9 KiB
C++
|
#pragma once
|
||
|
#include <boost/beast/websocket/stream.hpp>
|
||
|
#include <http/config.hpp>
|
||
|
#include <http/request.hpp>
|
||
|
#include <http/websocket_message.hpp>
|
||
|
#include <base/async_condition_variable.hpp>
|
||
|
#include <base/types.hpp>
|
||
|
|
||
|
namespace base::http {
|
||
|
|
||
|
// TODO: maybe pimpl?
|
||
|
|
||
|
struct WebSocketClient : public std::enable_shared_from_this<WebSocketClient> {
|
||
|
using RawStream = GenericStream;
|
||
|
using StreamType = beast::websocket::stream<RawStream>;
|
||
|
using EndpointType = typename GenericProtocol::endpoint;
|
||
|
|
||
|
using Ptr = std::shared_ptr<WebSocketClient>;
|
||
|
|
||
|
using MessagePtr = std::shared_ptr<WebSocketMessage>;
|
||
|
using ConstMessagePtr = std::shared_ptr<const WebSocketMessage>;
|
||
|
|
||
|
using MessageHandler = std::function<Awaitable<void>(Ptr, ConstMessagePtr)>;
|
||
|
using CloseHandler = std::function<Awaitable<void>(Ptr)>; // TODO: close reason?
|
||
|
|
||
|
struct Listener {
|
||
|
virtual ~Listener() = default;
|
||
|
|
||
|
virtual Awaitable<void> OnClose() = 0; // TODO: close reason
|
||
|
virtual Awaitable<void> OnMessage(ConstMessagePtr message) = 0;
|
||
|
// TODO: control frames
|
||
|
};
|
||
|
|
||
|
WebSocketClient(RawStream&& stream, Request& req)
|
||
|
: stream(std::move(stream)), sendCondition(stream.get_executor()), upgrade(req) {}
|
||
|
|
||
|
//~WebSocketClient() {
|
||
|
// logger.Info("~WebSocketClient");
|
||
|
//}
|
||
|
|
||
|
void SetListener(Listener* listener) {
|
||
|
this->listener = listener;
|
||
|
}
|
||
|
|
||
|
void Send(ConstMessagePtr message);
|
||
|
|
||
|
Awaitable<bool> Handshake();
|
||
|
|
||
|
Awaitable<void> Close();
|
||
|
|
||
|
|
||
|
Awaitable<void> CloseWithReason(const std::string& reason);
|
||
|
|
||
|
asio::ip::address Address();
|
||
|
|
||
|
Request& GetUpgradeRequest() { return upgrade; }
|
||
|
|
||
|
private:
|
||
|
StreamType stream;
|
||
|
|
||
|
std::vector<ConstMessagePtr> sendQueue;
|
||
|
|
||
|
Listener* listener{nullptr};
|
||
|
|
||
|
AsyncConditionVariable sendCondition;
|
||
|
bool sending { false };
|
||
|
bool closed = false;
|
||
|
bool forceClosed { false };
|
||
|
|
||
|
Request upgrade;
|
||
|
|
||
|
constexpr static u32 MAX_MESSAGES_IN_QUEUE = 256;
|
||
|
|
||
|
Awaitable<void> WriteEnd();
|
||
|
Awaitable<void> ReadEnd();
|
||
|
};
|
||
|
|
||
|
} // namespace base::http
|