comparison libervia/web/pages/_browser/bridge.py @ 1579:5db55d01ce05

browser (bridge): workaround to fix unicode dumping of JSON: in Brython 3.11, emoji are broken when dumped/parsed with `ensure_ascii`, and using `ensure_ascii=False` is not working (see https://github.com/brython-dev/brython/issues/2331). This work around this and https://github.com/brython-dev/brython/issues/2332 to make sure that emoji are transmitted correctly to other tabs.
author Goffi <goffi@goffi.org>
date Wed, 22 Nov 2023 16:31:36 +0100
parents be20e6ac9f22
children
comparison
equal deleted inserted replaced
1578:c57133362fb7 1579:5db55d01ce05
100 100
101 def send(self, data_type: str, data: dict) -> None: 101 def send(self, data_type: str, data: dict) -> None:
102 self.socket.send(json.dumps({ 102 self.socket.send(json.dumps({
103 "type": data_type, 103 "type": data_type,
104 "data": data 104 "data": data
105 })) 105 }, ensure_ascii=False))
106 106
107 def close(self) -> None: 107 def close(self) -> None:
108 log.debug("closing socket") 108 log.debug("closing socket")
109 self.broadcast_channel.ws = None 109 self.broadcast_channel.ws = None
110 self.socket.close() 110 self.socket.close()
173 # the first tab. 173 # the first tab.
174 self.check_connection_timer = timer.set_timeout(self.establish_connection, 20) 174 self.check_connection_timer = timer.set_timeout(self.establish_connection, 20)
175 # set of all known tab ids 175 # set of all known tab ids
176 self.tabs_ids = {tab_id} 176 self.tabs_ids = {tab_id}
177 self.post("salut_a_vous", { 177 self.post("salut_a_vous", {
178 "id": tab_id,
179 "profile": self.profile 178 "profile": self.profile
180 }) 179 })
181 window.bind("unload", self.on_unload) 180 window.bind("unload", self.on_unload)
182 self._wait_connection_fut = aio.Future() 181 self._wait_connection_fut = aio.Future()
183 182
199 @connecting_tab.setter 198 @connecting_tab.setter
200 def connecting_tab(self, connecting: bool) -> None: 199 def connecting_tab(self, connecting: bool) -> None:
201 if connecting: 200 if connecting:
202 if self.ws is None: 201 if self.ws is None:
203 self.ws = WebSocket(self) 202 self.ws = WebSocket(self)
204 self.post("connection", { 203 self.post("connection", {})
205 "tab_id": tab_id
206 })
207 aio.run(self._wait_for_ws()) 204 aio.run(self._wait_for_ws())
208 205
209 elif self.ws is not None: 206 elif self.ws is not None:
210 self.ws.close() 207 self.ws.close()
211 208
231 for handler in handlers: 228 for handler in handlers:
232 handler(*data["args"]) 229 handler(*data["args"])
233 230
234 def on_message(self, evt) -> None: 231 def on_message(self, evt) -> None:
235 data = json.loads(evt.data) 232 data = json.loads(evt.data)
233 # FIXME: we convert back to int, see FIXME in [post] for details
234 data["id"] = int(data["id"])
236 if data["type"] == "bridge": 235 if data["type"] == "bridge":
237 self.handle_bridge_signal(data) 236 self.handle_bridge_signal(data)
238 elif data["type"] == "salut_a_toi": 237 elif data["type"] == "salut_a_toi":
239 # this is a response from existing tabs 238 # this is a response from existing tabs
240 other_tab_id = data["id"] 239 other_tab_id = data["id"]
283 log.info(f"tab with id {other_tab_id} has been closed") 282 log.info(f"tab with id {other_tab_id} has been closed")
284 else: 283 else:
285 log.warning(f"unknown message type: {data}") 284 log.warning(f"unknown message type: {data}")
286 285
287 def post(self, data_type, data: dict): 286 def post(self, data_type, data: dict):
288 data["type"] = data_type 287 data["type"] = str(data_type)
289 data["id"] = tab_id 288 # FIXME: for some reason, JSON.stringify fail when a random.randint is used with
290 self.bc.postMessage(json.dumps(data)) 289 # Brython 3.11 . See https://github.com/brython-dev/brython/issues/2332,
290 # workaround may be removed once fixed version is used.
291 data["id"] = str(tab_id)
292 # FIXME: json.dumps doesn't support "ensure_ascii=False" and fails to correctly
293 # dump emoji. See https://github.com/brython-dev/brython/issues/2331, workaround
294 # may be removed once fixed version is used.
295 dumped = javascript.JSON.stringify(data)
296 self.bc.postMessage(dumped)
291 if data_type == "bridge": 297 if data_type == "bridge":
292 self.handle_bridge_signal(data) 298 self.handle_bridge_signal(data)
293 299
294 def on_unload(self, evt) -> None: 300 def on_unload(self, evt) -> None:
295 """Send a message to indicate that the tab is being closed""" 301 """Send a message to indicate that the tab is being closed"""