Delay emitter until NiceGUI-level handshake done (#4754)
This PR fix #4753, possibly paves the way to shifting the Socket.IO
intialization earlier.
Notable changes:
- [Handshake is done only when receiver server
ok](https://github.com/zauberzeug/nicegui/commit/793adb4814b382c755749289f9583fc90e0b24dd)
- [Retry emitting message repeatedly until handshake is
done](https://github.com/zauberzeug/nicegui/commit/a107315d1d117bd5ab5ce130a10e968c33532157)
Old logic:
- Handshake is done when we sent the message. Who cares how long that
message may take to reach the server
- If the handshake is not done, we wait 10ms and emit regardless.
- Meaning if the handshake is not done after 10ms, the message gets
lost.
New logic:
- We wait for the NiceGUI side to return True before considering the
handshake is done
- If the handshake is not done, we keep on retrying at 10ms interval
- Meaning if the handshake is not done after 10ms, the message does not
get lost.
About the handshakes:
- Engine.IO-level handshake, receiving `0{sid: "m-Lwo1fStO8e-QAbAAAU",
upgrades: [] ...`
- Socket.IO-level handshake, receiving
`40{"sid":"oxVbOYM32Hieu1anAAAV"}`
- Some components wait for this handshake to emit, because they need
`window.socket.id`, like Leaflet
- NiceGUI-level handshake, sending `420["handshake", {client_id:
"7b6b9df6-e24a-489c-9dd2-012a08b34a10"...` and receiving `430[true]`
- This PR refers to waiting for this handshake, as it is the most
important one.
- Before this handshake, any event emitted will not be registered, since
the Socket.IO ID is not associated with the `client_id` yet.