| 175 | } |
| 176 | |
| 177 | void NetworkManagerBase::CreateClient(INetworkHandler* handler, StringView endpoints, std::uint16_t defaultPort, std::uint32_t clientData) |
| 178 | { |
| 179 | if (_handler != nullptr) { |
| 180 | LOGE("[MP] Client already created"); |
| 181 | return; |
| 182 | } |
| 183 | |
| 184 | _state = NetworkState::Connecting; |
| 185 | _clientData = clientData; |
| 186 | _handler = handler; |
| 187 | |
| 188 | #if defined(DEATH_TARGET_EMSCRIPTEN) && defined(WITH_WEBSOCKET) |
| 189 | StringView firstEndpoint = endpoints.prefix(endpoints.findOr('|', endpoints.end()).begin()); |
| 190 | String proto = MakeClientSubProtocol(clientData); |
| 191 | |
| 192 | EmscriptenWebSocketCreateAttributes attrs; |
| 193 | emscripten_websocket_init_create_attributes(&attrs); |
| 194 | attrs.url = firstEndpoint.data(); |
| 195 | attrs.protocols = proto.data(); |
| 196 | attrs.createOnMainThread = EM_TRUE; |
| 197 | |
| 198 | // emscripten_websocket_new doesn't correctly catches exceptions in Emscripten 5.0.7 |
| 199 | //_emWsSocket = emscripten_websocket_new(&attrs); |
| 200 | _emWsSocket = safe_websocket_new(&attrs); |
| 201 | if (_emWsSocket <= 0) { |
| 202 | Reason reason; |
| 203 | switch (_emWsSocket) { |
| 204 | case EM_WS_ERR_SECURITY: |
| 205 | LOGE("[MP] WebSocket connection to \"{}\" failed due to security error (e.g., \"ws://\" from \"https://\")", firstEndpoint); |
| 206 | reason = Reason::SecurityPolicyViolation; |
| 207 | break; |
| 208 | case EM_WS_ERR_DOM: |
| 209 | LOGE("[MP] WebSocket connection to \"{}\" failed due to DOM error (e.g., browser blocked the connection)", firstEndpoint); |
| 210 | reason = Reason::SecurityPolicyViolation; |
| 211 | break; |
| 212 | case EM_WS_ERR_MALFORMED_URL: |
| 213 | LOGE("[MP] WebSocket connection to \"{}\" failed due to malformed URL", firstEndpoint); |
| 214 | reason = Reason::InvalidParameter; |
| 215 | break; |
| 216 | default: |
| 217 | LOGE("[MP] WebSocket connection to \"{}\" failed due to unknown error", firstEndpoint); |
| 218 | reason = Reason::Unknown; |
| 219 | break; |
| 220 | } |
| 221 | |
| 222 | OnPeerDisconnected({}, reason); |
| 223 | _state = NetworkState::None; |
| 224 | _handler = nullptr; |
| 225 | return; |
| 226 | } |
| 227 | |
| 228 | _emWsUrl = firstEndpoint; |
| 229 | LOGI("[MP] Connecting to \"{}\"", _emWsUrl); |
| 230 | |
| 231 | emscripten_websocket_set_onopen_callback(_emWsSocket, this, OnEmWsOpen); |
| 232 | emscripten_websocket_set_onmessage_callback(_emWsSocket, this, OnEmWsMessage); |
| 233 | emscripten_websocket_set_onerror_callback(_emWsSocket, this, OnEmWsError); |
| 234 | emscripten_websocket_set_onclose_callback(_emWsSocket, this, OnEmWsClose); |
nothing calls this directly
no test coverage detected