Subscribe to the Sessions WebSocket instead of polling #7
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
mobrule/kurageyomi#7
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent
#1 — PRD: Kurageyomi
What to build
Replace the 2s poll of
/Kurageyomi/api/Sessionswith Jellyfin's session push.Confirmed in use: pause and unpause resume with up to two seconds of lag, because the client
reports the change immediately but the phone only learns about it on its next poll. The clock
itself is right — this is purely how late the news arrives.
Jellyfin pushes session state over its WebSocket. A client sends
{"MessageType":"SessionsStart","Data":"0,1000"}and the server sendsSessionsmessages on that interval (
BasePeriodicWebSocketListener, which parses the Data field asdueTimeMs,periodMs), stopping onSessionsStop.Worth knowing before building it: pushing more often than every ten seconds does not get a
fresher Playhead while playing — the server reports whatever the client last sent, and clients
throttle progress to 10s. What the push buys is that pause, unpause and seeks beyond ~5s of
drift are reported immediately, so those arrive in one round trip instead of up to a poll
interval late. That is exactly the lag being felt.
Keep polling as a fallback for when the socket drops; do not let a dead socket silently freeze
the phone on a stale position.
Acceptance criteria
Blocked by
None - can start immediately
Implemented and deployed — awaiting verification, do not rebuild.
Landed in
main:web/src/sessionSocketState.ts(pure state machine, 19 tests), the socket plumbing inmain.ts, andtoPlaybackSessionFromSessionInfoinwire.ts.Three protocol facts corrected during the work, all now in
docs/websocket-notes.md:BasePeriodicWebSocketListenerhas no timer —IntervalMsis only a floor between event-driven sends, and nothing is pushed in response toSessionsStart. The first state still comes from REST after subscribing.ApiKey. Lowercaseapi_keyonly works whileEnableLegacyAuthorizationis enabled.SessionInfoDto(nestedPlayState.*), not our flat DTO — hence the separate mapper.ForceKeepAlivemust be answered. Ignoring it does not close the socket in 10.11.11, but drops the connection from the watchlist, so pushes stop while the socket still looks alive.Remaining to close this: confirm on the device that pause/unpause is now near-instant, and that DevTools → Network → WS shows a
101on/socket. If the socket never subscribes, the polling fallback means behaviour is unchanged from before rather than broken.Shipped in
ddce440�web/src/sessionSocketState.tsfollows sessions over the WebSocket with polling as the fallback. Closing.