Просмотр исходного кода

use client_id instead sid to identify browser tab

Rodja Trappe 1 год назад
Родитель
Сommit
0684f72858
3 измененных файлов с 18 добавлено и 20 удалено
  1. 1 0
      nicegui/client.py
  2. 13 18
      nicegui/nicegui.py
  3. 4 2
      nicegui/templates/index.html

+ 1 - 0
nicegui/client.py

@@ -38,6 +38,7 @@ class Client:
         self.environ: Optional[Dict[str, Any]] = None
         self.shared = shared
         self.on_air = False
+        self.disconnection: Optional[int] = None
 
         with Element('q-layout', _client=self).props('view="hhh lpr fff"').classes('nicegui-layout') as self.layout:
             with Element('q-page-container') as self.page_container:

+ 13 - 18
nicegui/nicegui.py

@@ -133,8 +133,8 @@ async def exception_handler_500(request: Request, exception: Exception) -> Respo
 
 
 @sio.on('handshake')
-def on_handshake(sid: str) -> bool:
-    client = get_client(sid)
+def on_handshake(sid: str, client_id: str) -> bool:
+    client = globals.clients.get(client_id)
     if not client:
         return False
     client.environ = sio.get_environ(sid)
@@ -152,10 +152,12 @@ def handle_handshake(client: Client) -> None:
 
 @sio.on('disconnect')
 def on_disconnect(sid: str) -> None:
-    client = get_client(sid)
-    if not client:
-        return
-    handle_disconnect(client)
+    query_bytes: bytearray = sio.get_environ(sid)['asgi.scope']['query_string']
+    query = urllib.parse.parse_qs(query_bytes.decode())
+    client_id = query['client_id'][0]
+    client = globals.clients.get(client_id)
+    if client:
+        client.disconnection = time.time()
 
 
 def handle_disconnect(client: Client) -> None:
@@ -168,8 +170,8 @@ def handle_disconnect(client: Client) -> None:
 
 
 @sio.on('event')
-def on_event(sid: str, msg: Dict) -> None:
-    client = get_client(sid)
+def on_event(_: str, msg: Dict) -> None:
+    client = globals.clients[msg['client_id']]
     if not client or not client.has_socket_connection:
         return
     handle_event(client, msg)
@@ -186,8 +188,8 @@ def handle_event(client: Client, msg: Dict) -> None:
 
 
 @sio.on('javascript_response')
-def on_javascript_response(sid: str, msg: Dict) -> None:
-    client = get_client(sid)
+def on_javascript_response(_: str, msg: Dict) -> None:
+    client = globals.clients[msg['client_id']]
     if not client:
         return
     handle_javascript_response(client, msg)
@@ -197,19 +199,12 @@ def handle_javascript_response(client: Client, msg: Dict) -> None:
     client.waiting_javascript_commands[msg['request_id']] = msg['result']
 
 
-def get_client(sid: str) -> Optional[Client]:
-    query_bytes: bytearray = sio.get_environ(sid)['asgi.scope']['query_string']
-    query = urllib.parse.parse_qs(query_bytes.decode())
-    client_id = query['client_id'][0]
-    return globals.clients.get(client_id)
-
-
 async def prune_clients() -> None:
     while True:
         stale_clients = [
             id
             for id, client in globals.clients.items()
-            if not client.shared and not client.has_socket_connection and client.created < time.time() - 60.0
+            if not client.shared and not client.has_socket_connection and (client.disconnection or client.created) < time.time() - 60.0
         ]
         for client_id in stale_clients:
             delete_client(client_id)

+ 4 - 2
nicegui/templates/index.html

@@ -141,6 +141,7 @@
           let handler = (...args) => {
             const data = {
               id: element.id,
+              client_id: window.client_id,
               listener_id: event.listener_id,
               args: stringifyEventArgs(args, event.args),
             };
@@ -188,7 +189,7 @@
             throw reason;
         }).then((result) => {
           if (request_id) {
-            window.socket.emit("javascript_response", {request_id, result});
+            window.socket.emit("javascript_response", {request_id, client_id: window.client_id, result});
           }
         });
       }
@@ -231,6 +232,7 @@
         mounted() {
           window.app = this;
           const query = {{ socket_io_js_query_params | safe }};
+          window.client_id = query.client_id;
           const url = window.location.protocol === 'https:' ? 'wss://' : 'ws://' + window.location.host;
           const extraHeaders = {{ socket_io_js_extra_headers | safe }};
           const transports = {{ socket_io_js_transports | safe }};
@@ -238,7 +240,7 @@
           window.socket = io(url, { path: "{{ prefix | safe }}/_nicegui_ws/socket.io", query, extraHeaders, transports });
           const messageHandlers = {
             connect: () => {
-              window.socket.emit("handshake", (ok) => {
+              window.socket.emit("handshake", window.client_id, (ok) => {
                 if (!ok) {
                   console.log('reloading because handshake failed')
                   window.location.reload();