Menu
Back to Documentation Index

Phase 2/3 Transition

Phase transition planning and implementation notes

SWIM WebSocket Phase 2/3 Transition Summary

Last Updated: 2026-01-16 14:00 UTC

Status: Phase 2 COMPLETE βœ… | Phase 3 Python SDK complete


πŸŽ‰ Phase 2 Complete!

All WebSocket functionality is production-ready:

ComponentStatus
WebSocket Serverβœ… Running on port 8090
External WSS Accessβœ… wss://perti.vatcscc.org/api/swim/v1/ws
Event Detectionβœ… Departures, arrivals, positions, TMIs
Database Authβœ… Validates against swim_api_keys
Tier Rate Limitsβœ… Connection limits enforced
Python SDKβœ… Ready for use

Session Log (2026-01-16)

Session 3 - Rate Limits + Completion

Completed:

1. Tier-based connection limits in WebSocketServer.php

- Tracks connectionsByTier counts

- Enforces limits on connect, decrements on disconnect

- Rejects with CONNECTION_LIMIT error when at max

- Shows tier in connect/disconnect logs

2. Tier limits:

| Tier | Max Connections |

|------|-----------------|

| public | 5 |

| developer | 50 |

| partner | 500 |

| system | 10,000 |

3. Documentation updated - All SWIM docs reflect completion

Session 2 - DB Auth + Python SDK

Completed:

1. Database authentication in WebSocketServer.php

- Validates API keys against dbo.swim_api_keys

- 5-minute key cache to reduce DB queries

- Checks is_active and expires_at

- Updates last_used_at on success

2. Python SDK - sdk/python/swim_client/

- Async WebSocket client with auto-reconnect

- Typed event data classes

- 4 example scripts

3. Poll interval reduced from 500ms to 100ms

Session 1 - Core Deployment

Completed:

  • WebSocket server deployed (port 8090)
  • Apache proxy configured
  • Event detection integrated
  • External WSS verified working

  • Architecture

    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚   ADL Daemon    │─────▢│   Event File    │◀────▢│  WebSocket Hub  β”‚
    β”‚  (15s refresh)  β”‚ emit β”‚  (IPC queue)    β”‚ poll β”‚  (Ratchet PHP)  β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                  100ms polling                β”‚
                                                               β”‚
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
                  β–Ό                β–Ό               β–Ό           β–Ό
             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚  CRC   β”‚      β”‚  vNAS  β”‚      β”‚SimAwareβ”‚  β”‚ Custom β”‚
             β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    


    Phase 3 Status

    TaskEst. HoursStatus
    Python SDK12hβœ… DONE
    Redis IPC4-6h⏸️ Deferred
    C# SDK12h⏳ As needed
    Java SDK12h⏳ As needed
    Message compression2h⏳ Low priority
    Historical replay8h⏳ Low priority
    Metrics dashboard4h⏳ Low priority

    Redis Decision

    Redis ($16/mo) deferred indefinitely. Current file-based IPC:

  • 100ms polling interval
  • ~50ms average latency added to 15-second cycle (0.3%)
  • Deploy Redis only when API caching layer needed

File Reference

Core WebSocket Files

FilePurpose
scripts/swim_ws_server.phpWebSocket daemon
scripts/swim_ws_events.phpEvent detection queries
api/swim/v1/ws/WebSocketServer.phpServer class (auth + rate limits)
api/swim/v1/ws/ClientConnection.phpClient wrapper
api/swim/v1/ws/SubscriptionManager.phpSubscription management
api/swim/v1/ws/swim-ws-client.jsJavaScript client

Python SDK Files

FilePurpose
sdk/python/swim_client/__init__.pyPackage exports
sdk/python/swim_client/client.pySWIMClient class
sdk/python/swim_client/events.pyEvent data classes
sdk/python/examples/basic_example.pySimple usage
sdk/python/examples/airport_monitor.pyAirport tracking
sdk/python/examples/position_tracker.pyPosition tracking
sdk/python/examples/tmi_monitor.pyTMI monitoring

Database Reference

swim_api_keys Table

CREATE TABLE dbo.swim_api_keys (
    id INT IDENTITY(1,1) PRIMARY KEY,
    api_key NVARCHAR(64) NOT NULL UNIQUE,
    tier NVARCHAR(20) NOT NULL DEFAULT 'public',
    owner_name NVARCHAR(100) NOT NULL,
    owner_email NVARCHAR(255),
    description NVARCHAR(500),
    expires_at DATETIME2,
    created_at DATETIME2 NOT NULL DEFAULT GETUTCDATE(),
    last_used_at DATETIME2,
    is_active BIT NOT NULL DEFAULT 1
);

Current Keys

KeyTierOwner
swim_dev_hp_testdeveloperHP

Create New Key

INSERT INTO dbo.swim_api_keys (api_key, tier, owner_name, owner_email, description)
VALUES (
    'swim_' + LOWER(CONVERT(VARCHAR(36), NEWID())),
    'developer',
    'Name',
    'email@example.com',
    'Description'
);


Operations Reference

Restart WebSocket Server

pkill -f swim_ws_server
rm -f /home/site/wwwroot/scripts/swim_ws.lock
nohup php /home/site/wwwroot/scripts/swim_ws_server.php --debug > /home/LogFiles/swim_ws.log 2>&1 &

Monitor Logs

tail -f /home/LogFiles/swim_ws.log

Test Python SDK

cd sdk/python
pip install -e .
python examples/basic_example.py swim_dev_hp_test


Event Types

EventDescription
flight.createdNew pilot connected
flight.departedWheels up (OFF time)
flight.arrivedWheels down (IN time)
flight.deletedPilot disconnected
flight.positionsBatched position updates
tmi.issuedNew GS/GDP issued
tmi.releasedTMI ended
system.heartbeatServer keepalive (30s)

Success Metrics

MetricTargetAchieved
External WSSWorkingβœ…
DB AuthImplementedβœ…
Tier LimitsEnforcedβœ…
Python SDKCompleteβœ…
Event latency< 15 sec~15 sec
Phase 2100%βœ…

Next Steps

1. Deploy rate limits - Files need to sync, then restart WS server

2. C#/Java SDKs - Build when consumers request

3. Metrics dashboard - Track usage patterns

4. Redis - Deploy when caching layer needed


Cost Summary

ComponentMonthly
SWIM_API (Azure SQL Basic)$5
WebSocket (self-hosted)$0
Redis (deferred)$0
Total$5