Moving from 1.x

Protocol 2.0 keeps the same ideas, channels, events and presence, but every message is JSON, joins are signed with Ed25519 instead of HMAC, and our servers keep no secret that can act as your app. Your app id stays the same. This is everything to change, in the order to change it.

1. Get 2.0 keys for your app

Sign in to the dashboard, open your app, and create its 2.0 keys. You get an API key (pk_…) for publishing and a private key for signing joins, and a .env file with PIKOMAN_APP, PIKOMAN_API_KEY and PIKOMAN_PRIVATE_KEY. The private key is shown once. The old app secret keeps working on 1.x until the switch.

2. Make your auth endpoint answer both

The request is the same, GET {auth_url}/{clientId}-{channel}. The answer changes from {"auth": "2:presence-…:…"} to {"token": "…"}, an EdDSA JWT; the quickstart has endpoints in Node and PHP. Tabs that are already open keep the old client until they reload, so for a while your endpoint gets both kinds. Tell them apart by the id:

  • 2.0 ids are strings such as c_8f3a1c9e2b7d4a6051e0c3b9, with no - in them: split {clientId}-{channel} at the first -. Answer with a token.
  • 1.x ids are numbers. Answer with the old HMAC join string, as today.
  • access works like the old permissions number: 3 for a full member. Leaving it out now means 0, listen only, so set it.
  • OfflineAuthenticator, for local experiments, now takes (data, privateKey, access) with the Ed25519 private key instead of the app secret.

3. Publish to both hosts during the rollout

Old tabs listen on ws.pikoman.se and new ones on next.pikoman.se, so until the switch send each event twice:

terminal
# 1.x tabs: the app secret
curl -X POST https://api.pikoman.se/orders/shipped -u "$PIKOMAN_APP:$PIKOMAN_APP_SECRET" -d '{"id": 1042}'
# 2.0 tabs: the API key
curl -X POST https://next-api.pikoman.se/orders/shipped -u "$PIKOMAN_APP:$PIKOMAN_API_KEY" -d '{"id": 1042}'

On 2.0, /{channel}/clients is a GET and returns member data as objects, and DELETE /kick-all answers with how many were closed. The rest is in Publishing over HTTP.

4. Ship the 2.0 client

terminal
npm install @pikoman/ws@next

It connects to next.pikoman.se by itself; remove any ws_address you set. Most code keeps working:

  • listen, listenPresence, on, off, send, members and getMembers are unchanged.
  • Connection ids are strings such as c_8f3a…, not numbers.
  • Member data arrive as objects. If you call JSON.parse on them, remove it.
  • Send objects with send directly; there is no need to JSON.stringify them first.
  • clientMessage(fn) gets (clientId, event, data), and serverMessage(fn) gets (data, event).
  • New: listenPrivate(name) for private channels, and refused(fn) when a join or send is turned down.

5. Check your channel names

  • Names starting with private- are now private channels: listen("private-…") throws. Rename public channels that start with it.
  • Names are 1 to 164 characters of A-Z a-z 0-9 _ - = @ , . ;. No spaces, /, : or letters outside A-Z.
  • Every connection is in the channel global: POST /global/{event} reaches everyone, and GET /global/stats counts them. Don't use the name for anything else.

6. Small differences in behaviour

  • The server drops a connection that sends nothing for 90 seconds, so a sleeping laptop leaves its presence channels. The client pings on its own; only a client you wrote yourself needs to.
  • The rate limit answer is {"op":"error","code":"rate_limited","channel":…} instead of 9:RATE_LIMIT.
  • A member without write access is still told when others join or leave, but does not get the member list on joining.

7. The switch

  1. When no open tab runs the old client any more (GET /{channel}/stats on api.pikoman.se says 0 for your busiest channels), stop publishing there and remove the HMAC branch of your auth endpoint.
  2. . When every app has moved, ws. and api.pikoman.se switch to 2.0 and @pikoman/ws 1.0.0 is released, connecting there.
  3. Then update to @pikoman/ws 1.0.0 and publish to api.pikoman.se again, with the API key.

A tab that still runs the old client after the switch is closed with code 4400, "protocol outdated", and works again after a reload.

Old and new on the wire

Only needed if you wrote your own client. Every 2.0 message is described in Protocol 2.0.

1.x 2.0 op
0:{id}connected
1:{channel}:{event}:{data}event
2:{channel}join / joined / member_joined
2:presence-…:{signature}:…join with token
3:{channel}error, code join_refused
4:{channel}leave / left / member_left
8:…send / client_event
9:RATE_LIMITerror, code rate_limited
16:{channel}:{members}members
64:{time}ping / pong

Previous: protocol and tokens The 1.x docs

We are rebuilding the dashboard

Self-service sign-up is closed while we do. Until the new dashboard is ready we set up apps by hand: write to us with a line about what you are building, and we will set up your app and get back to you.

Write to hello@pikoman.se