diff --git a/src/matchWebsocket.js b/src/matchWebsocket.js index 3f73dd3..9ce0746 100644 --- a/src/matchWebsocket.js +++ b/src/matchWebsocket.js @@ -392,6 +392,20 @@ function normalizeServerUrl(serverAddr, token) { return appendQuery(url, "token", token); } +function getServerEndpoint(url) { + return String(url || "").split("?")[0]; +} + +function getUrlToken(url) { + const match = String(url || "").match(/[?&]token=([^&#]+)/i); + if (!match?.[1]) return ""; + try { + return decodeURIComponent(match[1]); + } catch (_) { + return match[1]; + } +} + function emitMatchSocketState(state, extra = {}) { uni.$emit(MATCH_WS_STATE_EVENT, { state, @@ -763,10 +777,32 @@ export function connectMatchWebSocket(options = {}) { reconnecting = false, reconnectReason = "", } = options; - const url = normalizeServerUrl(serverAddr, token); const normalizedMatchId = normalizeId(matchId); const normalizedUserId = normalizeId(userId); const normalizedMode = Number(mode); + const incomingUrl = normalizeServerUrl(serverAddr, token); + const currentUrlToken = getUrlToken(currentContext?.url); + const shouldKeepAuthenticatedUrl = !!( + currentContext && + currentContext.matchId === normalizedMatchId && + getServerEndpoint(currentContext.url) === getServerEndpoint(incomingUrl) && + currentUrlToken && + !getUrlToken(incomingUrl) + ); + const url = shouldKeepAuthenticatedUrl ? currentContext.url : incomingUrl; + const resolvedServerAddr = shouldKeepAuthenticatedUrl + ? currentContext.serverAddr + : serverAddr; + const resolvedToken = shouldKeepAuthenticatedUrl + ? currentContext.token || currentUrlToken + : token; + + if (shouldKeepAuthenticatedUrl) { + console.log("[match-ws] keep authenticated url for same match", { + matchId: normalizedMatchId, + endpoint: getServerEndpoint(url), + }); + } if (!url || !normalizedMatchId) { console.log("[match-ws] missing serverAddr or matchId", options); @@ -799,10 +835,10 @@ export function connectMatchWebSocket(options = {}) { if (!isSameContext) reconnectAttempt = 0; const connectedOnce = isSameContext && currentContext?.connectedOnce === true; currentContext = { - serverAddr, + serverAddr: resolvedServerAddr, matchId: normalizedMatchId, userId: normalizedUserId, - token, + token: resolvedToken, url, mode: Number.isFinite(normalizedMode) ? normalizedMode : undefined, isMelee: