68 lines
1.9 KiB
C++
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
|