#Installation
#Readme
Primitive to help establish, maintain and operate a websocket connection.
makeWS
- sets up a web socket connection with a buffered sendcreateWS
- sets up a web socket connection that disconnects on cleanupcreateWSState
- creates a reactive signal containing the readyState of a websocketmakeReconnectingWS
- sets up a web socket connection that reconnects if involuntarily closedcreateReconnectingWS
- sets up a reconnecting web socket connection that disconnects on cleanupmakeHeartbeatWS
- wraps a reconnecting web socket to send a heart beat and reconnect if the answer fails
All of them return a WebSocket instance extended with a message
prop containing an accessor for the last received message for convenience and the ability to receive messages to send before the connection is opened.
#How to use it
const ws = createWS("ws://localhost:5000");
const state = createWSState(ws);
const states = ["Connecting", "Connected", "Disconnecting", "Disconnected"];
ws.send("it works");
createEffect(on(ws.message, msg => console.log(msg), { defer: true }));
return <p>Connection: {states[state()]}</p>;
const socket = makeHeartbeatWS(
makeReconnectingWS(`ws://${location.hostName}/api/ws`, undefined, { timeout: 500 }),
{ message: "👍" },
);
// with the primitives starting with `make...`, one needs to manually clean up:
socket.send("this will reconnect if connection fails");
#Definitions
/** Arguments of the primitives */
type WSProps = [url: string, protocols?: string | string[]];
type WSMessage = string | ArrayBufferLike | ArrayBufferView | Blob;
type WSReadyState = WebSocket.CONNECTING | WebSocket.OPEN | WebSocket.CLOSING | WebSocket.CLOSED;
type WSEventMap = {
close: CloseEvent;
error: Event;
message: MessageEvent;
open: Event;
};
type ReconnectingWebSocket = WebSocket & {
reconnect: () => void;
// ws.send.before is meant to be used by heartbeat
send: ((msg: WSMessage) => void) & { before: () => void };
};
type WSHeartbeatOptions = {
/**
* Heartbeat message being sent to the server in order to validate the connection
* @default "ping"
*/
message?: WSMessage;
/**
* The time between messages being sent in milliseconds
* @default 1000
*/
interval?: number;
/**
* The time after the heartbeat message being sent to wait for the next message in milliseconds
* @default 1500
*/
wait?: number;
};
If you want to use the messages as a signal, have a look at the event-listener
package:
import { createWS } from "@solid-primitives/websocket";
import { createEventSignal } from "@solid-primitives/event-listener";
const ws = createWS("ws://localhost:5000");
const messageEvent = createEventSignal(ws, "message");
const message = () => messageEvent().data;
Otherwise, you can simply use the message event to get message.data:
import { createStore } from "solid-js/store";
import { createReconnectingWS, WSMessage } from "@solid-primitives/websocket";
const ws = createReconnectingWS("ws://localhost:5000");
const [messages, setMessages] = createStore<WSMessage[]>();
ws.addEventListener("message", (ev) => setMessages(messages.length, ev.data));
<For each={() => messages}>
{(message) => ...}
</For>
#Setting up a websocket server
While you can use this primitive with solid-start, it already provides a package for websockets that handles both the server and the client side:
import { createWebSocketServer } from "solid-start/websocket";
import server$ from "solid-start/server";
const pingPong = createWebSocketServer(
server$(function (webSocket) {
webSocket.addEventListener("message", async msg => {
try {
// Parse the incoming message
let incomingMessage = JSON.parse(msg.data);
console.log(incomingMessage);
switch (incomingMessage.type) {
case "ping":
webSocket.send(
JSON.stringify([
{
type: "pong",
data: {
id: incomingMessage.data.id,
time: Date.now(),
},
},
]),
);
break;
}
} catch (err: any) {
// Report any exceptions directly back to the client. As with our handleErrors() this
// probably isn't what you'd want to do in production, but it's convenient when testing.
webSocket.send(JSON.stringify({ error: err.stack }));
}
});
}),
);
Otherwise, in order to set up your own production-use websocket server, we recommend packages like
#Demo
You may view a working example here: https://primitives.solidjs.community
#Changelog
See CHANGELOG.md