On Cinetomi, users discover films on their phone but often want to finish watching on a bigger screen. The classic path is obvious: open the site on your computer, log in, find the film again. Three steps of friction. Our goal: tap "Watch on Desktop" on the phone, and the film continues on the computer from the exact second it left off.
How the flow works
In the browser, cinetomi.com shows a QR code and opens a session channel. When you scan it with "Watch on Desktop" in the app, the phone sends a one-time handoff token to that channel. The browser validates the token, receives the user's session and the film position, and starts playback.
The critical design decision: the QR contains no session data, only a short-lived channel id. Session information is never embedded in anything visible on screen.
Token generation on the Go side
Handoff tokens are single-use with a 60-second lifetime:
func CreateHandoff(userID, filmID string, position int) (string, error) {
token := randomToken(32)
err := rdb.Set(ctx, "handoff:"+token, HandoffPayload{
UserID: userID,
FilmID: filmID,
Position: position,
}, 60*time.Second).Err()
return token, err
}
func ConsumeHandoff(token string) (*HandoffPayload, error) {
// GetDel: read and delete; the token can't be used twice
val, err := rdb.GetDel(ctx, "handoff:"+token).Result()
...
}Thanks to GetDel, the token is deleted the moment it's read; someone photographing the QR can't replay it.
The only thing a user should feel during a device switch is continuity: the film resumes from the same second, the volume from the same level.
What we learned
- The lifetime should be aggressively short. 60 seconds is plenty for the scan habit; anything longer is just risk.
- Embedding the position (which second) in the token makes "continue where you left off" free.
- The hard part isn't the protocol, it's the edge cases: what if the phone screen locks, the browser tab goes to background, or two browsers are open at once?
The result is a success that's easy to measure: after the feature shipped, desktop viewing sessions started predominantly through the QR path.
Product manager & mobile developer. Writes about product, performance and good interfaces.