Draft. The packages work and are tested against Pikoman and Pusher, but are not published yet.
Switch from Pusher and keep your subscribe and bind
Pikoman has packages with the same calls as Pusher's libraries. You change an import and your keys.
Your channels, events, subscribe, bind, trigger and your auth endpoint
stay as they are.
Under the surface the packages speak Pikoman, so we still never hold a secret of yours: you sign with an
Ed25519 key and we keep only the public half. Laravel Echo works through the same package, so
Echo.private, Echo.join, whisper and toOthers() work as before.
- In the browser
- One import
- On the server
- The library and its keys
- Price
- Free to 100 connections, then €49 a month
1. Get your keys
Sign in at the dashboard with GitHub and create an app. Your browser makes the keys; the private ones are shown once.
| At Pusher | At Pikoman | |
|---|---|---|
| In the browser | Key a1b2c3d4e5f6a7b8c9d0 and a cluster |
App id app-yourapp, no cluster |
| Publishing | App id, key and secret | An API key sk_…, which may be limited to publishing |
| Letting users into private channels | The same secret | The app's private key, one line of base64 |
| What the provider holds | Your secret | Public keys only |
2. Laravel
Download the driver, install it and change .env. Your events, routes/channels.php and ShouldBroadcast classes stay the same.
mkdir -p packages
curl -o packages/pikoman-compat-laravel-0.1.0.zip https://pikoman.se/downloads/pikoman-compat-laravel-0.1.0.zip
composer config repositories.pikoman artifact ./packages
composer require pikoman/compat-laravel
npm install https://pikoman.se/downloads/pikoman-compat-0.1.0.tgzThen the keys in .env. VITE_PUSHER_APP_KEY keeps its name, so Echo needs no new setting.
BROADCAST_CONNECTION=pusher
PUSHER_APP_ID=1234567
PUSHER_APP_KEY=a1b2c3d4e5f6a7b8c9d0
PUSHER_APP_SECRET=f0e1d2c3b4a5...
PUSHER_APP_CLUSTER=eu
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"BROADCAST_CONNECTION=pikoman
PIKOMAN_APP=app-yourapp
PIKOMAN_API_KEY=sk_...
PIKOMAN_PRIVATE_KEY=MC4CAQAwBQYDK2Vw...
# Only for encrypted channels. Your own key, never sent to us:
# openssl rand -base64 32
PIKOMAN_ENCRYPTION_KEY=...
VITE_PUSHER_APP_KEY="${PIKOMAN_APP}"
VITE_PUSHER_APP_CLUSTER=euIn resources/js/echo.js, one line changes: the import.
import Echo from "laravel-echo";
import Pusher from "pusher-js";
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: "pusher",
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
forceTLS: true,
});import Echo from "laravel-echo";
import Pusher from "@pikoman/compat";
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: "pusher",
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
forceTLS: true,
});
Then php artisan config:clear and npm run build. Your listeners stay as they are:
Echo.private(`orders.${userId}`)
.listen("OrderShipped", (e) => console.log(e.order.id));
Echo.join(`room.${roomId}`)
.here((users) => showUsers(users))
.joining((user) => addUser(user))
.leaving((user) => removeUser(user))
.whisper("typing", { name: me.name });3. pusher-js without Laravel
Install it with npm install https://pikoman.se/downloads/pikoman-compat-0.1.0.tgz. The import and the key change; subscribe, bind and trigger do not.
import Pusher from "pusher-js";
const pusher = new Pusher("a1b2c3d4e5f6a7b8c9d0", {
cluster: "eu",
channelAuthorization: { endpoint: "/pusher/auth" },
});
const room = pusher.subscribe("presence-room");
room.bind("new-message", (data) => show(data));
room.trigger("client-typing", { on: true });import Pusher from "@pikoman/compat";
const pusher = new Pusher("app-yourapp", {
cluster: "eu",
channelAuthorization: { endpoint: "/pusher/auth" },
});
const room = pusher.subscribe("presence-room");
room.bind("new-message", (data) => show(data));
room.trigger("client-typing", { on: true });4. Your server
The library and its settings change. trigger and authorizeChannel take the same
arguments, so the code that calls them, your auth endpoint included, does not.
import Pusher from "pusher";
const pusher = new Pusher({
appId: "1234567",
key: "a1b2c3d4e5f6a7b8c9d0",
secret: process.env.PUSHER_SECRET,
cluster: "eu",
});import Pusher from "@pikoman/compat/server";
const pusher = new Pusher({
app: "app-yourapp",
apiKey: process.env.PIKOMAN_API_KEY,
privateKey: process.env.PIKOMAN_PRIVATE_KEY,
});await pusher.trigger("orders", "order-shipped", { id: 1042 });
app.post("/pusher/auth", (req, res) => {
const { socket_id, channel_name } = req.body;
if (!mayJoin(req.user, channel_name)) return res.sendStatus(403);
res.send(pusher.authorizeChannel(socket_id, channel_name, {
user_id: req.user.id,
user_info: { name: req.user.name },
}));
});PHP without Laravel is not covered yet. Write to hello@pikoman.se if you need it, and we will add it.
5. Move without downtime
- Deploy the server change and the browser change together. New page loads connect to Pikoman.
- Pages that were open before the deploy still listen at Pusher. If that matters, publish to both for a day: keep the old Pusher client next to the new one and call
triggeron each. - When the Pusher dashboard shows no connections, cancel the Pusher plan.
What the adapter covers
| Pusher feature | With the adapter |
|---|---|
| Public, private and presence channels | Yes |
Presence members (here, joining, leaving, members.count) | Yes, counted per user as at Pusher |
Client events (client-…, Echo's whisper) | Yes, 10 a second per connection, as at Pusher |
trigger to one or many channels | Yes |
toOthers() and socket_id | Yes. The sender's id travels in the event's data, which then has to be an object, as Laravel's always is |
private-encrypted- channels | Yes. Your backend keeps the master key (PIKOMAN_ENCRYPTION_KEY, or encryptionMasterKeyBase64 as in Pusher's library) and we never see it. Encrypted channels |
| Channel queries from the server library | Not yet; GET /channels works over HTTP |
| Webhooks | Pikoman's own webhooks, in a different format |
| User sign-in, watchlists, cache channels | No |
| Pusher's iOS and Android libraries, push notifications (Beams) | No |
Need something marked "not yet"? Write to hello@pikoman.se and we will add it.
Channel names follow the same rules as at Pusher: up to 164 characters from A-Z a-z 0-9 _ - = @ , . ;.
Try it on staging first
The free plan has 100 connections and 200,000 messages a day, enough to run your staging site on Pikoman before you move production.