Adapters
SSE
Integrate crossws with server-sent events and fetch-api.
If your deployment target does not supports handling WebSocket upgrades, crossws SSE adapter allows to add integration based on web platform standards (fetch
and EventSource
)
This is an experimental adapter and requires a custom
WebsocketSSE
client to connect.Usage
Server side
HTTP/2 + TLS is recommended in order to increase browser limitations about number of SSE connections (from 6 to 100) and also to allow bidirectional messaging with streaming.
Define adapter:
import sseAdapter from "crossws/adapters/sse";
const ws = sseAdapter({
bidir: true, // Enable bidirectional messaging support
hooks: {
upgrade(request) {
// In case of bidirectional mode, extra auth is recommended based on request
// You can return a new Response() instead to abort
return {
headers: {},
};
},
open(peer) {
// Use this hook to send messages to peer
peer.send(`Welcome ${peer}`);
},
message(peer, message) {
// Accepting messages from peer (bidirectional mode)
console.log(`Message from ${peer}: ${message}`); // Message from <id>: ping
},
},
});
Inside your web server handler:
async fetch(request) {
// Handle crossws upgrade
if (
request.headers.get("accept") === "text/event-stream" ||
request.headers.has("x-crossws-id")
) {
return ws.fetch(request);
}
// Your normal application logic
return new Response("default page")
}
Client side
In order to make communication with server, we need a special WebsocketSSE
client.
import { WebsocketSSE } from "crossws/websocket/sse";
const ws = new WebsocketSSE("https://<server_address>", { bdir: true });
ws.addEventListener("open", () => {
ws.send("ping");
});
ws.addEventListener("message", (event) => {
console.log("Received:", event.data);
});
Behind the scenes,
WebSocketSSE
, uses EventSource
to receive messages from server. In order to send messages to the server, it tries to make another connection stream using same peer id and if failed, fallback to fetch
for each message.
In theory, it is possible to have communication on a single HTTP/2 connection, however, due to a current limitation in fetch standard we need 2 connections, one for receiving messages and one for sending.See
test/fixture/sse.ts
for demo and src/adapters/sse.ts
for implementation.