space-game001/src/network/WebSocketClient.h
Vladislav Khorev 7ccda081b0 Fixing bugs
2026-03-06 23:15:56 +03:00

68 lines
1.9 KiB
C++

#pragma once
#ifdef NETWORK
#include "WebSocketClientBase.h"
#include <vector>
#include <atomic>
#include <memory>
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
namespace ZL {
// Lock-free SPSC double-buffer: producer pushes to one buffer, consumer swaps and drains the other.
// No mutexes; avoids contention under high message load.
class WebSocketClient : public WebSocketClientBase {
private:
boost::asio::io_context& ioc_;
std::unique_ptr<boost::beast::websocket::stream<boost::beast::tcp_stream>> ws_;
boost::beast::flat_buffer buffer_;
// Incoming messages: I/O thread pushes, main thread drains in Poll()
using MessageBuf = std::vector<std::string>;
MessageBuf readBuffer0_;
MessageBuf readBuffer1_;
std::atomic<MessageBuf*> readProducerBuf_;
std::atomic<MessageBuf*> readConsumerBuf_;
// Outgoing messages: main thread pushes in Send(), doWrite()/completion drains
using WriteBuf = std::vector<std::shared_ptr<std::string>>;
WriteBuf writeBuffer0_;
WriteBuf writeBuffer1_;
std::atomic<WriteBuf*> writeProducerBuf_;
std::atomic<WriteBuf*> writeConsumerBuf_;
WriteBuf* currentWriteBuf_ = nullptr;
size_t currentWriteIndex_ = 0;
std::atomic<bool> isWriting_{ false };
bool connected = false;
void startAsyncRead();
void processIncomingMessage(const std::string& msg);
public:
explicit WebSocketClient(boost::asio::io_context& ioc)
: ioc_(ioc)
, readProducerBuf_(&readBuffer0_)
, readConsumerBuf_(&readBuffer1_)
, writeProducerBuf_(&writeBuffer0_)
, writeConsumerBuf_(&writeBuffer1_)
{}
void Connect(const std::string& host, uint16_t port) override;
void Disconnect() override;
void Poll() override;
void Send(const std::string& message) override;
void doWrite();
bool IsConnected() const override { return connected; }
};
}
#endif