simple-ws2
TypeScript icon, indicating that this package has built-in type declarations

1.0.1 • Public • Published

Simple Websocket 2

Simple, fast & lightweight websocket server and client for NodeJS and browsers.

MIT License

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.

Authors

Package Sidebar

Install

npm i simple-ws2

Weekly Downloads

1

Version

1.0.1

License

MIT

Unpacked Size

20.3 kB

Total Files

24

Last publish

Collaborators

  • jlalmes