Sync Socket
A desktop daemon can keep your other computers' clones current by listening for pushes
instead of polling. Connect a Phoenix Channels client (protocol 2.0.0) to
wss://git.vianet.us/socket/sync/websocket?vsn=2.0.0
with a
personal access token
that has the read_api
or api
scope.
Authenticating
Send the token as the websocket subprotocol base64url.bearer.phx.<token>, the token Base64-encoded without padding,
which is what Phoenix's JavaScript client sends for its authToken
option. Prefer it: query strings end up in proxy logs. A client that can't set a
subprotocol may add &token=<token>
to the URL instead.
An IP address may connect 30 times a minute, and an account may have 10 joined channels at
once; the next join is refused with too many connections. A join is refused
with unauthorized once the token is revoked or expired, or the account is banned,
deleted or must set up two-factor authentication. Open connections are dropped when any
of that happens, when the token expires and when an admin loses admin rights.
Push events
Join the sync:pushes
topic; the reply carries the server's server_time. Every push, merge or new
branch in a repository you can read then arrives as a push
event:
{"project_id": 42, "path_with_namespace": "alice/app",
"ssh_url_to_repo": "git@host:alice/app.git", "http_url_to_repo": "https://host/alice/app.git",
"ref": "refs/heads/main", "before": "<old sha, 40 zeros for a new branch>", "after": "<new sha>",
"pusher": "alice", "pushed_at": "2026-10-16T12:00:00Z",
"mirror_sources": [{"provider": "github", "remote_repo_name": "alice/app"}]}
mirror_sources
lists the repository's pull mirrors for its maintainers; everyone else gets an empty list.
Catching up
After a reconnect, send catch_up
with the last server_time
you saw
as since
(ISO 8601). The reply's pushes
holds the newest push per
repository and branch at or after since, looking back 30 days at most, to the
second (so you may see one push again), newest first, at most 500; truncated
is true
when more matched, so fetch everything instead. A channel answers one catch_up
every 10 seconds (too many requests
otherwise); an unreadable since
is refused with invalid since
and any other event with unknown event.