WebSocket Streaming
Receive real-time article events and user notifications via WebSocket connections.
Overview
MisarBlog's WebSocket server delivers real-time events without polling. Two channels are available: user notifications and per-article live updates.
WebSocket API Reference
Full schema, close codes, heartbeat, and reconnection patterns.
SSE — Newsletter Progress
Track newsletter send progress via Server-Sent Events.
Channels
wss://api.misar.io/blog/ws/notifications
Subscribe to receive events for the authenticated user:
| Event type | Trigger |
|---|---|
new_subscriber | Someone subscribes to your newsletter |
new_comment | A comment is posted on your article |
article_reaction | A reader reacts to your article |
milestone | View count milestone reached |
const ws = new WebSocket(
`wss://api.misar.io/blog/ws/notifications?token=${apiKey}`
);
ws.onmessage = (e) => {
const { type, ...payload } = JSON.parse(e.data);
if (type === "new_subscriber") {
showToast(`New subscriber: ${payload.subscriber.email}`);
}
};wss://api.misar.io/blog/ws/articles/:slug
Subscribe to live engagement metrics for any article:
| Event type | Trigger |
|---|---|
view_update | View count changes |
reaction_update | Reaction counts change |
const ws = new WebSocket(
`wss://api.misar.io/blog/ws/articles/my-first-post?token=${apiKey}`
);
ws.onmessage = (e) => {
const { type, viewCount } = JSON.parse(e.data);
if (type === "view_update") {
counter.textContent = viewCount.toLocaleString();
}
};Authentication
Query parameter vs header
Browser clients cannot set Authorization headers on WebSocket connections. Use ?token=mbk_... for browser environments. Node.js clients can use the Authorization: Bearer header.
const ws = new WebSocket(`wss://api.misar.io/blog/ws/notifications?token=${apiKey}`);import WebSocket from "ws";
const ws = new WebSocket("wss://api.misar.io/blog/ws/notifications", {
headers: { Authorization: `Bearer ${apiKey}` },
});Heartbeat
The server sends a ping frame every 30 seconds. Most WebSocket libraries handle the pong response automatically. If no pong is received within 30 seconds, the connection is closed with code 1001.
Reconnection
function connectWs(apiKey: string, channel: string) {
let delay = 1_000;
let ws: WebSocket;
function connect() {
ws = new WebSocket(`wss://api.misar.io/blog/ws/${channel}?token=${apiKey}`);
ws.onopen = () => { delay = 1_000; };
ws.onclose = () => setTimeout(connect, delay = Math.min(delay * 2, 30_000));
return ws;
}
return connect();
}