mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-07-26 12:08:15 +00:00
3.2 KiB
3.2 KiB
KoalaSync Architecture
This document describes the communication flows and internal logic of the KoalaSync system.
1. Extension Startup & Connection
- Initialization: On startup,
background.jsreads settings (Server URL, Last Room) fromchrome.storage.sync. - WebSocket Handshake:
- Background creates a
new WebSocketto/socket.io/?EIO=4&transport=websocket&version=1.0.0&token=.... - Server performs security checks:
- IP Rate Limit: Checks if the IP has exceeded 10 connections/min.
- Auth Token: If a server token is required, it must match.
- Version Check: Client version must be
>= MIN_VERSION.
- Server responds with an Engine.IO handshake (packet type
0). - Background sends
40to join the default Socket.IO namespace. - Server responds with
40.
- Background creates a
- Room Join: If a Room ID is stored, Background emits
42["join_room", {...}]. - Reconnect Logic: If the connection drops, Background uses an exponential backoff (1s, 2s, 4s... max 30s) to reconnect.
2. Media Event Synchronization
When a user presses Play/Pause in a synchronized tab:
- Detection:
content.jslistens to nativeplay/pauseevents on the<video>element. - Reporting:
content.jssends aCONTENT_EVENTmessage tobackground.js. - Emission:
background.jsemits42["play"|"pause", {...}]to the server. - Relay: The Server forwards the event to all other sockets in the same room.
- Reception: Other Extensions receive the event via WebSocket.
- Execution:
background.jssends aSERVER_COMMANDto itscontent.js. - Control:
content.jscallsvideo.play()orvideo.pause().- Note: It uses
isProcessingCommandto prevent feedback loops.
- Note: It uses
3. Two-Phase Force Sync
This protocol ensures all peers are paused and buffered at the exact same timestamp before resuming playback.
- Initiation: User clicks "Force Sync" in the popup.
- Preparation:
- Popup asks Content Script for the current time.
- Background emits
FORCE_SYNC_PREPAREwithtargetTime.
- Coordination:
- Peers receive
PREPARE,content.jspauses and seeks. - Once
video.readyState >= 3(buffered),content.jssendsFORCE_SYNC_ACK. - Background forwards ACK to the Initiator via Server.
- Peers receive
- Execution:
- Initiator collects ACKs. Once all peers have responded (or 5s timeout), Initiator emits
FORCE_SYNC_EXECUTE. - All peers receive
EXECUTEand callvideo.play().
- Initiator collects ACKs. Once all peers have responded (or 5s timeout), Initiator emits
4. Peer Lifecycle
- Join: Server sends
ROOM_DATAto the joiner andPEER_STATUS (joined)to others. - Leave:
- Manual: User clicks "Leave". Popup sends
LEAVE_ROOMto Background -> Server. - Pruning: If a socket disconnects, the Server automatically broadcasts
PEER_STATUS (left)and deletes the room if empty.
- Manual: User clicks "Leave". Popup sends
- Heartbeat:
content.jssends a status heartbeat every 15s to keep the peer list updated with current playback states.
5. Service Worker Keep-alive
Manifest V3 Service Workers are ephemeral. To keep the connection alive:
chrome.alarmstriggers every 15 seconds.- The alarm listener checks the WebSocket
readyState. - If not
OPEN, it triggers aconnect()attempt. - This keeps the background process "awake" enough to handle incoming WebSocket messages.