docs: complete repository documentation update for v1.0.0-RC5 features

This commit is contained in:
Timo
2026-04-22 11:54:54 +02:00
parent 830f8c44b1
commit 1d2237aab6
5 changed files with 117 additions and 148 deletions
+29 -43
View File
@@ -3,54 +3,40 @@
This document describes the communication flows and internal logic of the KoalaSync system.
## 1. Extension Startup & Connection
- **Initialization**: On startup, `background.js` reads settings (Server URL, Last Room) from `chrome.storage.sync`.
- **Initialization**: On startup, `background.js` reads settings (Server URL, Username, Last Room) from `chrome.storage.sync`.
- **WebSocket Handshake**:
1. Background creates a `new WebSocket` to `/socket.io/?EIO=4&transport=websocket&version=1.0.0&token=...`.
1. Background creates a `new WebSocket` to `/socket.io/?EIO=4&transport=websocket&version=1.0.0`.
2. 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`.
3. Server responds with an Engine.IO handshake (packet type `0`).
4. Background sends `40` to join the default Socket.IO namespace.
5. Server responds with `40`.
- **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.
- **IP Rate Limit**: Checks if the IP has exceeded connection limits.
- **Protocol Version**: Client must match the server's protocol (currently `1.0.0`).
3. Server responds with Engine.IO handshake (`0`) and the client joins the namespace (`40`).
- **Room Join**: Background emits `JOIN_ROOM` containing `roomId`, `password`, `peerId`, and `username`.
- **Deduplication**: If a user joins with a `peerId` that already has an active socket, the server kills the old socket to prevent "Ghost Peers".
## 2. Media Event Synchronization
When a user presses Play/Pause in a synchronized tab:
1. **Detection**: `content.js` listens to native `play`/`pause` events on the `<video>` element.
2. **Reporting**: `content.js` sends a `CONTENT_EVENT` message to `background.js`.
3. **Emission**: `background.js` emits `42["play"|"pause", {...}]` to the server.
4. **Relay**: The Server forwards the event to all other sockets in the same room.
5. **Reception**: Other Extensions receive the event via WebSocket.
6. **Execution**: `background.js` sends a `SERVER_COMMAND` to its `content.js`.
7. **Control**: `content.js` calls `video.play()` or `video.pause()`.
- *Note*: It uses `isProcessingCommand` to prevent feedback loops.
When a user interacts with a video:
1. **Detection**: `content.js` listens to native events (`play`, `pause`, `seeked`) on the `<video>` element.
2. **Prevention of Loops**: Uses `lastTargetState` to distinguish between user actions and programmatic actions triggered by the extension.
3. **Reporting**: `content.js` sends a `CONTENT_EVENT` to `background.js`.
4. **Relay**: The Server forwards the event to all other peers in the room.
5. **Execution**: Remote peers receive the command and call `video.play()`, `video.pause()`, or `video.currentTime = targetTime`.
## 3. Two-Phase Force Sync
This protocol ensures all peers are paused and buffered at the exact same timestamp before resuming playback.
1. **Initiation**: User clicks "Force Sync" in the popup.
2. **Preparation**:
- Popup asks Content Script for the current time.
- Background emits `FORCE_SYNC_PREPARE` with `targetTime`.
3. **Coordination**:
- Peers receive `PREPARE`, `content.js` pauses and seeks.
- Once `video.readyState >= 3` (buffered), `content.js` sends `FORCE_SYNC_ACK`.
- Background forwards ACK to the Initiator via Server.
4. **Execution**:
- Initiator collects ACKs. Once all peers have responded (or 5s timeout), Initiator emits `FORCE_SYNC_EXECUTE`.
- All peers receive `EXECUTE` and call `video.play()`.
Ensures all peers are frame-perfect and buffered before resuming:
1. **Prepare**: Initiator sends `FORCE_SYNC_PREPARE` with the target timestamp.
2. **Buffer**: Peers seek and pause. Once buffered (`readyState >= 3`), they send a `FORCE_SYNC_ACK`.
3. **Execute**: Once the Initiator collects ACKs (or after a 5s timeout), they send `FORCE_SYNC_EXECUTE`.
4. **Resume**: All peers call `play()` simultaneously.
## 4. Peer Lifecycle
- **Join**: Server sends `ROOM_DATA` to the joiner and `PEER_STATUS (joined)` to others.
- **Leave**:
- **Manual**: User clicks "Leave". Popup sends `LEAVE_ROOM` to Background -> Server.
- **Pruning**: If a socket disconnects, the Server automatically broadcasts `PEER_STATUS (left)` and deletes the room if empty.
- **Heartbeat**: `content.js` sends a status heartbeat every 15s to keep the peer list updated with current playback states.
## 4. Peer Lifecycle & Dual Heartbeat
To maintain a clean room state and eliminate "Ghost Peers":
- **Session Heartbeat (Background)**: Every 30 seconds, `background.js` sends an "I'm alive" signal to the server. This keeps you in the room even if no video is playing.
- **Video Heartbeat (Content)**: Every 15 seconds, `content.js` sends current playback metadata (time, title, state) if a video is found.
- **Server Pruning**: The server runs a "Reaper" every 2 minutes. If a peer has sent **zero** activity (no events and no heartbeats) for 5 minutes, they are forcefully disconnected.
- **Immediate Cleanup**: Rooms are deleted instantly when the last peer leaves or disconnects.
## 5. Service Worker Keep-alive
Manifest V3 Service Workers are ephemeral. To keep the connection alive:
1. `chrome.alarms` triggers every 15 seconds.
2. The alarm listener checks the WebSocket `readyState`.
3. If not `OPEN`, it triggers a `connect()` attempt.
4. This keeps the background process "awake" enough to handle incoming WebSocket messages.
## 5. Security & Stability
- **Service Worker Lifecycle**: Uses `chrome.alarms` to prevent the Manifest V3 service worker from suspending while in an active room.
- **Rate Limiting**: Server-side per-socket and per-IP rate limits to prevent sync-spamming or DoS.
- **Noise Filtering**: Uses a curated blacklist of domains (Search Engines, Social Media) to declutter the "Target Tab" selector in the popup.
- **Diagnostics**: A "Dev" tab provides real-time access to the underlying `<video>` state (`readyState`, `paused`, `currentTime`) for easier troubleshooting.