space-game001/src/network/WebSocketClientEmscripten.cpp
2026-02-10 21:06:21 +03:00

94 lines
3.5 KiB
C++

#ifdef NETWORK
#ifdef EMSCRIPTEN
#include "WebSocketClientEmscripten.h"
#include <iostream>
#include <SDL2/SDL.h>
namespace ZL {
void WebSocketClientEmscripten::Connect(const std::string& host, uint16_t port) {
// Формируем URL. Обратите внимание, что в Web часто лучше использовать ws://localhost
std::string url = "ws://" + host + ":" + std::to_string(port);
EmscriptenWebSocketCreateAttributes attr = {
url.c_str(),
nullptr,
EM_TRUE // create_on_main_thread
};
socket_ = emscripten_websocket_new(&attr);
emscripten_websocket_set_onopen_callback(socket_, this, onOpen);
emscripten_websocket_set_onmessage_callback(socket_, this, onMessage);
emscripten_websocket_set_onerror_callback(socket_, this, onError);
emscripten_websocket_set_onclose_callback(socket_, this, onClose);
}
void WebSocketClientEmscripten::Send(const std::string& message) {
if (connected && socket_ > 0) {
auto signedMsg = SignMessage(message);
std::cout << "[WebWS] Sending message: " << signedMsg << std::endl;
emscripten_websocket_send_utf8_text(socket_, signedMsg.c_str());
}
}
void WebSocketClientEmscripten::Poll() {
// Локальная очередь для минимизации времени блокировки мьютекса
std::queue<std::string> localQueue;
{
std::lock_guard<std::mutex> lock(queueMutex);
if (messageQueue.empty()) return;
std::swap(localQueue, messageQueue);
}
while (!localQueue.empty()) {
const std::string& msg = localQueue.front();
std::cout << "[WebWS] Processing message: " << msg << std::endl;
// Передаем в базовый класс для парсинга игровых событий (BOXES, UPD, и т.д.)
HandlePollMessage(msg);
localQueue.pop();
}
}
// --- Колбэки ---
EM_BOOL WebSocketClientEmscripten::onOpen(int eventType, const EmscriptenWebSocketOpenEvent* e, void* userData) {
auto* self = static_cast<WebSocketClientEmscripten*>(userData);
self->connected = true;
std::cout << "[WebWS] Connection opened" << std::endl;
return EM_TRUE;
}
EM_BOOL WebSocketClientEmscripten::onMessage(int eventType, const EmscriptenWebSocketMessageEvent* e, void* userData) {
std::cout << "[WebWS] onMessage " << std::endl;
auto* self = static_cast<WebSocketClientEmscripten*>(userData);
if (e->isText && e->data) {
std::string msg(reinterpret_cast<const char*>(e->data), e->numBytes);
std::lock_guard<std::mutex> lock(self->queueMutex);
self->messageQueue.push(msg);
}
return EM_TRUE;
}
EM_BOOL WebSocketClientEmscripten::onError(int eventType, const EmscriptenWebSocketErrorEvent* e, void* userData) {
auto* self = static_cast<WebSocketClientEmscripten*>(userData);
self->connected = false;
std::cerr << "[WebWS] Error detected" << std::endl;
return EM_TRUE;
}
EM_BOOL WebSocketClientEmscripten::onClose(int eventType, const EmscriptenWebSocketCloseEvent* e, void* userData) {
auto* self = static_cast<WebSocketClientEmscripten*>(userData);
self->connected = false;
std::cout << "[WebWS] Connection closed" << std::endl;
return EM_TRUE;
}
}
#endif
#endif