simple-ws2
v1.0.1
Published
Simple, fast & lightweight websocket server and client for NodeJS and browsers
Downloads
6
Maintainers
Readme
Simple Websocket 2
Simple, fast & lightweight websocket server and client for NodeJS and browsers.
Contributions & PRs are always welcome! 🙌
Why use simple-ws2
?
Simple API send & receive serialized JSON messages.
Native rooms implementation, join & leave rooms and broadcast messages.
Robust design ping-pong and healthcheck utilities included.
First class Typescript support.
It's tiny, fast and it's open source!
Installation
npm install simple-ws2
API
Server
import { SimpleWsServer } from "simple-ws2";
import { Server } from "http";
import express from "express";
// Create a server (Vanilla)
const wss = new SimpleWsServer({ port: PORT });
// Create a server (with Express)
const app = express();
const server = new Server(app);
const wss = new SimpleWsServer({ server, path: '/' });
server.listen(PORT);
// Listen for new connections
wss.on("connection", (ws: SimpleWsSocket) => {
// Receive messages
ws.onMessage<any>("message-type", (data) => { ... })
// Send messages
ws.sendMessage<any>("message-type", data)
// Join room
ws.joinRoom("room-id")
// Leave room
ws.leaveRoom("room-id")
// Listen for socket close event
ws.on("close", () => { ... })
// Broadcast message to all connected sockets
wss.broadcastMessage<any>("*", "message-type", data)
// Broadcast message to all sockets in room
wss.broadcastMessage<any>("room-id", "message-type", data)
})
Client
import { SimpleWsClient } from "simple-ws2";
// Create a websocket
const ws = new SimpleWsClient(WSS_ENDPOINT_URL);
// Receive messages
ws.onMessage<any>("message-type", (data) => { ... })
// Send messages
ws.sendMessage<any>("message-type", data)
Example usage (Game lobby)
Server
// Import 'simple-ws2'
import { SimpleWsServer } from "simple-ws2";
const port = 8081;
// Pass any additional 'ws' server options here
const wss = new SimpleWsServer({ port });
// Listen for new ws connections
wss.on("connection", (ws) => {
// Listen for the "authenticate" message
ws.onMessage("authenticate", async ({ token }) => {
// Validate user token
const userId = validateToken(token);
if (!userId) {
// Send "error" message to client
ws.sendMessage("error", { message: "Token is invalid" });
} else {
// Set userId in websocket metadata for later reference
ws.metadata.set("userId", userId);
// Send "authenticated" message to client
ws.sendMessage("authenticated", { userId });
}
});
// Listen for the "join-lobby" message
ws.onMessage("join-lobby", ({ lobbyId }) => {
// Check if this websocket is authenticated
const userId = ws.metadata.get("userId");
if (!userId) {
ws.sendMessage("error", { message: "You are not authenticated" });
} else {
// Join the websocket room
ws.joinRoom(lobbyId);
// Broadcast "user-joined-lobby" message to all websockets in room
wss.broadcastMessage(lobbyId, "user-joined-lobby", { lobbyId, userId });
}
});
// Listen for websocket "close" event and cleanup any side-effects
serverWs.on("close", () => {
serverWs.rooms.forEach((lobbyId) => {
// Leave the websocket room
serverWs.leaveRoom(lobbyId);
const userId = ws.metadata.get("userId");
if (userId) {
// Broadcast "user-left-lobby" message to all remaining websockets in room
wss!.broadcastMessage(lobbyId, "user-left-lobby", { lobbyId, userId });
}
});
});
});
Client
// Import 'simple-ws2'
import { SimpleWsClient } from "simple-ws2";
const port = 8081;
let lobby = [];
// Create a new WebSocket
const ws = new SimpleWsClient(`http://localhost:${port}`);
// Send a 'authenticate' message with token payload
ws.sendMessage("authenticate", { token: "some-auth-token" });
// Listen for the "authenticated" message
ws.onMessage("authenticated", ({ userId }) => {
// Send "join-lobby" message with lobbyId payload
ws.sendMessage("join-lobby", { lobbyId: "some-lobby-id" });
});
// Listen for the "user-joined-lobby" message
ws.onMessage("user-joined-lobby", ({ lobbyId, userId }) => {
// Update lobby state with new userId
lobby = [...lobby, userId];
});
// Listen for the "user-left-lobby" message
ws.onMessage("user-left-lobby", ({ lobbyId, userId }) => {
// Update lobby state with removed userId
lobby = lobby.filter((lobbyUserId) => lobbyUserId !== userId);
});
ws.onMessage("error", ({ message }) => {
// Do something with error messages
});
Acknowledgements
This package was inspired by these projects.