SSX3LobbyServer/lib/http/websocket_client.hpp

79 lines
1.9 KiB
C++
Raw Normal View History

#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