Package Exports
- wsmini
- wsmini/src/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (wsmini) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
WsMini
Minimalist WebSocket client and server for real-time applications with RPC, PubSub, Rooms and Game state synchronization based on WS https://github.com/websockets/ws
Features
- 🚀 Lightweight and easy
- 📡 RPC - Remote Procedure Calls with built-in error handling
- 🎯 PubSub - Very simple Publish/Subscribe system
- 🏠 Room-based management system
- 🎮 Game-ready with fixed timestep game loop and state synchronization
Installation
npm install wsmini
Examples
1. RPC - Remote Procedure Calls
Simple request/response pattern with error handling.
Complete server example located in src/examples/server/rpc.mjs.
const wsServer = new WSServerPubSub({ port: 8888 });
wsServer.addRpc('add', (data) => {
if (typeof data?.n1 != 'number') throw new WSServerError('n1 must be a number');
if (typeof data?.n2 != 'number') throw new WSServerError('n2 must be a number');
return data.n1 + data.n2;
});
wsServer.start();
Complete client example located in src/examples/client/rpc.js.
const ws = new WSClient('ws://localhost:8888');
await ws.connect();
const result = await ws.rpc('add', {n1: 5, n2: 3});
console.log(result);
2. PubSub - Channel Based Messaging
Subscribe to channels and broadcast messages.
Complete server example located in src/examples/server/chat.mjs.
const wsServer = new WSServerPubSub({ port: 8887 });
wsServer.addChannel('chat', {
hookPub: (msg, user) => ({
time: Date.now(),
user: 'Anon. ' + user.id.slice(0, 4),
msg,
}),
});
wsServer.start();
Complete client example located in src/examples/client/chat.js.
const ws = new WSClient('ws://localhost:8887');
await ws.connect();
ws.sub('chat', msg => console.log(`${msg.user}: ${msg.msg}`));
ws.pub('chat', 'Hello everyone!');
3. Room Management
Create/join rooms with built-in message handling.
Complete server example located in src/examples/server/room.mjs.
const wsServer = new WSServerRoomManager({
port: 8889,
maxUsersByRoom: 10,
roomClass: class extends WSServerRoom {
onMsg(msg, clientMeta, client) {
return {
time: Date.now(),
msg,
};
}
},
});
Client:
const ws = new WSClientRoom('ws://localhost:8889');
const room1 = await ws.roomCreateOrJoin('room 1');
room1.onMessage(data => console.log(data.msg, data.time));
room1.send('Hello room 1!');
4. Game State Synchronization
- Main loop with fixed timestep
- Register custom commands and patches.
- Game list and player list synchronization.
Complete server example located in src/examples/server/game.mjs.
class Player {
constructor(x, y) {
this.x = x;
this.y = y;
}
tick(dt) {
// update the player data (take dt into account)
}
}
const wsServer = new WSServerRoomManager({
maxUsersByRoom: 2,
roomClass: class extends WSServerGameRoom {
onCreate(roomName) {
// Initialize the world as you see fit
this.world = {
players: [
new Player(0, 0),
new Player(10, 10),
],
};
this.startMainLoop();
}
onCmdMove(msg, clientMeta) {
// define custom commands
}
onTick(dt) {
for (const player of this.world.players) player.tick(dt);
}
onPatch() {
return this.world;
}
},
});
wsServer.start();
complete client example located in src/examples/client/game.js.
const ws = new WSClientRoom('ws://localhost:8890');
const game1 = await ws.roomJoin('game1');
game1.onMessage(world => {
// update the game state on the client side
});
document.addEventListener('keydown', e => {
// Send custom command
if (e.key === 'ArrowUp') game1.sendCmd('move', {dir: 'up'});
if (e.key === 'ArrowDown') game1.sendCmd('move', {dir: 'down'});
if (e.key === 'ArrowLeft') game1.sendCmd('move', {dir: 'left'});
if (e.key === 'ArrowRight') game1.sendCmd('move', {dir: 'right'});
});
function render() {
requestAnimationFrame(render);
// render the game state
}
requestAnimationFrame(render);