| 1262 | } |
| 1263 | |
| 1264 | void NetworkManagerBase::ProcessWsQueue(INetworkHandler* handler) |
| 1265 | { |
| 1266 | SmallVector<WsQueuedEvent, 0> pending; |
| 1267 | { |
| 1268 | std::unique_lock<Spinlock> lock(_wsLock); |
| 1269 | std::swap(pending, _wsPendingEvents); |
| 1270 | } |
| 1271 | |
| 1272 | for (auto& ev : pending) { |
| 1273 | switch (ev.type) { |
| 1274 | case WsQueuedEvent::Type::Open: { |
| 1275 | Peer wsPeer = Peer::FromWebSocket(ev.peer); |
| 1276 | ConnectionResult result = OnPeerConnected(wsPeer, ev.clientData); |
| 1277 | if (result.IsSuccessful()) { |
| 1278 | std::unique_lock lock(_lock); |
| 1279 | _connectedPeers.push_back(wsPeer); |
| 1280 | } else { |
| 1281 | // Reject the connection |
| 1282 | ev.peer->close(ReasonToWsCloseCode(result.FailureReason), ReasonToString(result.FailureReason)); |
| 1283 | } |
| 1284 | break; |
| 1285 | } |
| 1286 | case WsQueuedEvent::Type::Close: { |
| 1287 | OnPeerDisconnected(Peer::FromWebSocket(ev.peer), WsCloseCodeToReason(ev.closeCode, true)); |
| 1288 | break; |
| 1289 | } |
| 1290 | case WsQueuedEvent::Type::Message: { |
| 1291 | if DEATH_LIKELY(ev.data.size() >= 1) { |
| 1292 | std::uint8_t pktType = (std::uint8_t)ev.data[0]; |
| 1293 | if DEATH_UNLIKELY(pktType == (std::uint8_t)ClientPacketType::Ping && ev.data.size() >= 1 + 8 + 4) { |
| 1294 | // Intercept Ping: read timestamp + reported RTT, update per-peer RTT, echo Pong |
| 1295 | std::uint64_t timestamp; |
| 1296 | std::uint32_t reportedRtt; |
| 1297 | std::memcpy(×tamp, ev.data.data() + 1, 8); |
| 1298 | std::memcpy(&reportedRtt, ev.data.data() + 9, 4); |
| 1299 | { |
| 1300 | std::unique_lock<Spinlock> lock(_wsLock); |
| 1301 | auto it = _wsPeers.find(ev.peer); |
| 1302 | if DEATH_LIKELY(it != _wsPeers.end()) { |
| 1303 | it->second.rtt = reportedRtt; |
| 1304 | } |
| 1305 | } |
| 1306 | // Echo timestamp back as Pong |
| 1307 | std::uint8_t pong[1 + 8]; |
| 1308 | pong[0] = (std::uint8_t)ServerPacketType::Pong; |
| 1309 | std::memcpy(pong + 1, ×tamp, 8); |
| 1310 | ev.peer->sendBinary(std::string(reinterpret_cast<const char*>(pong), sizeof(pong))); |
| 1311 | } else { |
| 1312 | handler->OnPacketReceived(Peer::FromWebSocket(ev.peer), 0, |
| 1313 | pktType, arrayView((const std::uint8_t*)ev.data.data() + 1, ev.data.size() - 1)); |
| 1314 | } |
| 1315 | } |
| 1316 | break; |
| 1317 | } |
| 1318 | } |
| 1319 | } |
| 1320 | } |
| 1321 |
no test coverage detected