Overview
Posture!Posture!Posture! uses Chrome’s port-based messaging system for real-time communication between extension components. This architecture enables continuous data flow for pose detection updates (~10 messages per second) while maintaining efficient, persistent connections.Messaging Architecture
Communication Channels
- Options ↔ Background: Relay posture detection messages
- Popup ↔ Options: Synchronize state and send commands
- Background → Content: Forward posture messages to active tab
Port-Based Messaging
What are Ports?
Ports are persistent messaging channels created withchrome.runtime.connect(). Unlike one-time messages (chrome.runtime.sendMessage), ports remain open for continuous bidirectional communication.
Use ports when you need ongoing communication. Use one-time messages for single request/response exchanges.
Port Lifecycle
- Connect:
chrome.runtime.connect({ name: 'port-name' }) - Send:
port.postMessage({ data }) - Receive:
port.onMessage.addListener(callback) - Disconnect: Automatic on page close or manual
port.disconnect()
Channel 1: Options → Background → Content
Flow: Posture Detection Messages
Purpose: Send real-time posture updates from Options page to Content script on active tabs.- Options (Sender)
- Background (Relay)
- Content (Receiver)
File: When posture changes are detected:Message format:Frequency: ~10 messages per second (every 100ms during detection)
src/pages/Options/Options.tsxThe Options page connects to the Background script on mount:Channel 2: Popup ↔ Options
Flow: State Synchronization and Commands
Purpose: Synchronize UI state between Popup and Options page, and send user commands.- Popup (Initiator)
- Options (Responder)
File: Sending commands:
src/pages/Popup/Popup.jsxThe Popup connects to the Options page when it opens:Message Actions
| Action | Direction | Payload | Purpose |
|---|---|---|---|
SET_IS_WATCHING | Options → Popup | { isWatching: boolean } | Sync tracking state |
SET_IS_PANEL_OPEN | Options → Popup | { isPanelOpen: boolean } | Sync panel state |
TOGGLE_WATCHING | Popup → Options | { isWatching: boolean } | Start/stop tracking |
RESET_POSTURE | Popup → Options | (none) | Reset baseline |
SET_GOOD_POSTURE_DEVIATION | Popup → Options | { GOOD_POSTURE_DEVIATION: number } | Update threshold |
Message Formats
Posture Messages
Command Messages
Port vs One-Time Messages
- Port-Based (Used)
- One-Time (Alternative)
When to use:
- Continuous communication (pose updates every 100ms)
- Bidirectional state sync (Popup ↔ Options)
- Long-lived connections during component lifecycle
- Persistent connection (no reconnection overhead)
- Two-way communication
- Lower latency for frequent messages
Background as Message Relay
The Background service worker acts as a message broker because:- Content scripts can’t directly communicate with extension pages (Options/Popup)
- Only background scripts can use
chrome.tabs.sendMessage - Background scripts persist across page navigations
Relay Implementation
chrome.tabs API - only background scripts do. The relay pattern is necessary for extension architecture.
Connection Error Handling
Popup When Options is Closed
Port Disconnection
Missing Active Tab
What happens if Content script isn't loaded?
What happens if Content script isn't loaded?
If
chrome.tabs.sendMessage is sent to a tab where the content script hasn’t loaded yet (e.g., chrome:// pages where content scripts don’t run), the message is silently dropped. This is expected behavior and doesn’t cause errors.Badge Updates
The extension badge shows tracking status (“ON” or “OFF”):- Options page:
handleToggleCamera() - Popup commands:
TOGGLE_WATCHINGaction
Performance Considerations
Message Frequency
- Posture updates: ~10 messages/second (100ms interval)
- State sync: On-demand (only when Popup opens or state changes)
- Commands: User-triggered (low frequency)
Port Persistence
- Component unmounts
- Page closes
- Manual
port.disconnect()
Memory Management
Ports are automatically cleaned up when pages close. No manual cleanup is required in this extension.
Debugging Messages
Chrome DevTools
- Background script: Right-click extension icon → Inspect service worker
- Options page: Right-click Options page → Inspect
- Popup: Right-click Popup → Inspect
- Content script: Regular page DevTools → check Console
Logging Messages
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Port connection fails | Target component not loaded | Check if Options page is open |
| Messages not received | Wrong port name | Verify port names match (relay-detection, set-options) |
| Content script silent | Script not injected | Check manifest content_scripts matches pattern |
| Disconnection errors | Page closed/navigated | Add onDisconnect listener |
Inspecting message flow in DevTools
Inspecting message flow in DevTools
- Open Background script console
- Add breakpoint in
handlePostureMessage - Start tracking in Options page
- Watch messages flow through Background to Content
- Check Content script console for received messages