#ifdef NETWORK #ifdef EMSCRIPTEN #include "WebSocketClientEmscripten.h" #include #include 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); std::string url = "wss://api.spacegame.fishrungames.com"; 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); connected = false; } void WebSocketClientEmscripten::Disconnect() { if (socket_ > 0) { emscripten_websocket_close(socket_, 1000, "User disconnected"); emscripten_websocket_delete(socket_); socket_ = 0; } connected = false; } void WebSocketClientEmscripten::flushOutgoingQueue() { std::lock_guard lock(outgoingMutex); if (!socket_) return; while (!outgoingQueue.empty()) { const std::string &m = outgoingQueue.front(); emscripten_websocket_send_utf8_text(socket_, m.c_str()); outgoingQueue.pop(); } } void WebSocketClientEmscripten::Send(const std::string& message) { std::string signedMsg = SignMessage(message); { std::lock_guard lock(outgoingMutex); if (connected && socket_ > 0) { std::cout << "[WebWS] Sending message (immediate): " << signedMsg << std::endl; emscripten_websocket_send_utf8_text(socket_, signedMsg.c_str()); return; } outgoingQueue.push(signedMsg); std::cout << "[WebWS] Queued outgoing message (waiting for open): " << signedMsg << std::endl; } } void WebSocketClientEmscripten::Poll() { // Локальная очередь для минимизации времени блокировки мьютекса std::queue localQueue; 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(userData); self->connected = true; std::cout << "[WebWS] Connection opened" << std::endl; self->flushOutgoingQueue(); return EM_TRUE; } EM_BOOL WebSocketClientEmscripten::onMessage(int eventType, const EmscriptenWebSocketMessageEvent* e, void* userData) { std::cout << "[WebWS] onMessage " << std::endl; auto* self = static_cast(userData); if (e->isText && e->data) { std::string msg(reinterpret_cast(e->data), e->numBytes); self->messageQueue.push(msg); } return EM_TRUE; } EM_BOOL WebSocketClientEmscripten::onError(int eventType, const EmscriptenWebSocketErrorEvent* e, void* userData) { auto* self = static_cast(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(userData); self->connected = false; std::cout << "[WebWS] Connection closed" << std::endl; return EM_TRUE; } } #endif #endif