From b11328160a996fc880334c931ab72b2c5f931c52 Mon Sep 17 00:00:00 2001 From: Lendemor Date: Wed, 8 Jan 2025 17:17:34 +0100 Subject: [PATCH 1/3] fix duplicate tab issue --- reflex/.templates/web/utils/state.js | 14 ++++++++------ reflex/app.py | 26 +++++++++++++++++++++----- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/reflex/.templates/web/utils/state.js b/reflex/.templates/web/utils/state.js index 41dbee44629..98dfefd6947 100644 --- a/reflex/.templates/web/utils/state.js +++ b/reflex/.templates/web/utils/state.js @@ -300,10 +300,7 @@ export const applyEvent = async (event, socket) => { // Send the event to the server. if (socket) { - socket.emit( - "event", - event, - ); + socket.emit("event", event); return true; } @@ -408,9 +405,10 @@ export const connect = async ( path: endpoint["pathname"], transports: transports, autoUnref: false, + query: { token: getToken() }, }); // Ensure undefined fields in events are sent as null instead of removed - socket.current.io.encoder.replacer = (k, v) => (v === undefined ? null : v) + socket.current.io.encoder.replacer = (k, v) => (v === undefined ? null : v); function checkVisibility() { if (document.visibilityState === "visible") { @@ -461,6 +459,10 @@ export const connect = async ( event_processing = false; queueEvents([...initialEvents(), event], socket); }); + socket.current.on("new_token", async (new_token) => { + token = new_token; + window.sessionStorage.setItem(TOKEN_KEY, new_token); + }); document.addEventListener("visibilitychange", checkVisibility); }; @@ -488,7 +490,7 @@ export const uploadFiles = async ( return false; } - const upload_ref_name = `__upload_controllers_${upload_id}` + const upload_ref_name = `__upload_controllers_${upload_id}`; if (refs[upload_ref_name]) { console.log("Upload already in progress for ", upload_id); diff --git a/reflex/app.py b/reflex/app.py index 259fcca29c5..d0c9592c458 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -15,6 +15,7 @@ import platform import sys import traceback +import uuid from datetime import datetime from pathlib import Path from types import SimpleNamespace @@ -1528,14 +1529,18 @@ def __init__(self, namespace: str, app: App): self.sid_to_token = {} self.app = app - def on_connect(self, sid, environ): + async def on_connect(self, sid, environ): """Event for when the websocket is connected. Args: sid: The Socket.IO session id. environ: The request information, including HTTP headers. """ - pass + query_string = environ.get("QUERY_STRING") + query_params = dict( + qc.split("=") for qc in query_string.split("&") if "=" in qc + ) + await self.link_token_to_sid(sid, query_params.get("token")) def on_disconnect(self, sid): """Event for when the websocket disconnects. @@ -1575,9 +1580,6 @@ async def on_event(self, sid, data): **{k: v for k, v in fields.items() if k not in ("handler", "event_actions")} ) - self.token_to_sid[event.token] = sid - self.sid_to_token[sid] = event.token - # Get the event environment. if self.app.sio is None: raise RuntimeError("Socket.IO is not initialized.") @@ -1610,3 +1612,17 @@ async def on_ping(self, sid): """ # Emit the test event. await self.emit(str(constants.SocketEvent.PING), "pong", to=sid) + + async def link_token_to_sid(self, sid, token): + """Link a token to a session id. + + Args: + sid: The Socket.IO session id. + token: The client token. + """ + if token in self.sid_to_token.values() and sid != self.token_to_sid.get(token): + token = uuid.uuid4().hex + await self.emit("new_token", token, to=sid) + + self.token_to_sid[token] = sid + self.sid_to_token[sid] = token From 2825500e2693dbac3257d23b077bc33f9e11f23a Mon Sep 17 00:00:00 2001 From: Lendemor Date: Thu, 9 Jan 2025 11:22:40 +0100 Subject: [PATCH 2/3] review changes --- reflex/app.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/reflex/app.py b/reflex/app.py index d0c9592c458..d5d74e36218 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -15,6 +15,7 @@ import platform import sys import traceback +import urllib.parse import uuid from datetime import datetime from pathlib import Path @@ -1536,10 +1537,7 @@ async def on_connect(self, sid, environ): sid: The Socket.IO session id. environ: The request information, including HTTP headers. """ - query_string = environ.get("QUERY_STRING") - query_params = dict( - qc.split("=") for qc in query_string.split("&") if "=" in qc - ) + query_params = urllib.parse.parse_qs(environ.get("QUERY_STRING")) await self.link_token_to_sid(sid, query_params.get("token")) def on_disconnect(self, sid): @@ -1621,7 +1619,7 @@ async def link_token_to_sid(self, sid, token): token: The client token. """ if token in self.sid_to_token.values() and sid != self.token_to_sid.get(token): - token = uuid.uuid4().hex + token = str(uuid.uuid4()) await self.emit("new_token", token, to=sid) self.token_to_sid[token] = sid From 2f215a350e6e3ca544b8f9d158d6b09605a4d993 Mon Sep 17 00:00:00 2001 From: Lendemor Date: Thu, 9 Jan 2025 16:21:35 +0100 Subject: [PATCH 3/3] fix issue --- reflex/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reflex/app.py b/reflex/app.py index d5d74e36218..7c172598848 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -1538,7 +1538,7 @@ async def on_connect(self, sid, environ): environ: The request information, including HTTP headers. """ query_params = urllib.parse.parse_qs(environ.get("QUERY_STRING")) - await self.link_token_to_sid(sid, query_params.get("token")) + await self.link_token_to_sid(sid, query_params.get("token", [])[0]) def on_disconnect(self, sid): """Event for when the websocket disconnects. @@ -1611,7 +1611,7 @@ async def on_ping(self, sid): # Emit the test event. await self.emit(str(constants.SocketEvent.PING), "pong", to=sid) - async def link_token_to_sid(self, sid, token): + async def link_token_to_sid(self, sid: str, token: str): """Link a token to a session id. Args: