Root cause: Server logs showed "ClientMessage has no subtype with attribute 'type' equal to 'state'" - the client was using incorrect message types that the aiosendspin library couldn't parse. Changes: - Fix state reporting: 'state' → 'client/state' with proper payload - Fix heartbeat: 'ping' → 'client/time' with microsecond timestamp - Fix disconnect: 'disconnect' → 'client/goodbye' with reason - Send initial client/state immediately after server/hello (required) - Handle server/time and group/update message types - Reduce state report interval from 1s to 5s (was flooding server) The server was disconnecting after 5 seconds because it couldn't parse the malformed 'state' messages, triggering a "spec violation" timeout. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
54 lines
1.9 KiB
Dart
54 lines
1.9 KiB
Dart
/// Timing constants for polling intervals, cache durations, and delays
|
|
class Timings {
|
|
Timings._();
|
|
|
|
/// WebSocket heartbeat/ping interval to keep connection alive
|
|
static const Duration heartbeatInterval = Duration(seconds: 30);
|
|
|
|
/// Player state polling interval (for selected player updates)
|
|
static const Duration playerPollingInterval = Duration(seconds: 5);
|
|
|
|
/// Local player state report interval
|
|
/// Note: Sendspin protocol only requires state on changes, not periodic reports.
|
|
/// This is mainly for local UI position tracking. Set to 5s to reduce server traffic.
|
|
static const Duration localPlayerReportInterval = Duration(seconds: 5);
|
|
|
|
/// Player list cache duration before refresh
|
|
static const Duration playersCacheDuration = Duration(minutes: 5);
|
|
|
|
/// Home screen row cache duration (recently played, discover sections)
|
|
static const Duration homeRowCacheDuration = Duration(minutes: 10);
|
|
|
|
/// WebSocket reconnection delay
|
|
static const Duration reconnectDelay = Duration(seconds: 3);
|
|
|
|
/// Command timeout for API requests
|
|
static const Duration commandTimeout = Duration(seconds: 30);
|
|
|
|
/// Connection timeout for initial WebSocket handshake
|
|
static const Duration connectionTimeout = Duration(seconds: 10);
|
|
|
|
/// Search debounce delay
|
|
static const Duration searchDebounce = Duration(milliseconds: 500);
|
|
|
|
/// Delay after track change before updating state
|
|
static const Duration trackChangeDelay = Duration(milliseconds: 500);
|
|
}
|
|
|
|
/// Library and pagination constants
|
|
class LibraryConstants {
|
|
LibraryConstants._();
|
|
|
|
/// Default page size for library items
|
|
static const int defaultPageSize = 100;
|
|
|
|
/// Maximum items to load for "all" library requests
|
|
static const int maxLibraryItems = 5000;
|
|
|
|
/// Number of items per batch for recent albums
|
|
static const int recentAlbumsBatchSize = 5;
|
|
|
|
/// Default limit for recent/random items
|
|
static const int defaultRecentLimit = 10;
|
|
}
|