mirror of
https://github.com/nvms/prsm.git
synced 2025-12-16 16:10:54 +00:00
README
This commit is contained in:
parent
2965ecb548
commit
31a53fb274
@ -2,31 +2,33 @@
|
|||||||
|
|
||||||
Mesh is a command-based WebSocket server and client framework designed for scalable, multi-instance deployments. It uses Redis to coordinate connections, rooms, and metadata across servers, enabling reliable horizontal scaling. Mesh includes built-in ping/latency tracking, automatic reconnection, and a simple command API for clean, asynchronous, RPC-like communication.
|
Mesh is a command-based WebSocket server and client framework designed for scalable, multi-instance deployments. It uses Redis to coordinate connections, rooms, and metadata across servers, enabling reliable horizontal scaling. Mesh includes built-in ping/latency tracking, automatic reconnection, and a simple command API for clean, asynchronous, RPC-like communication.
|
||||||
|
|
||||||
* [Quickstart](#quickstart)
|
- [Quickstart](#quickstart)
|
||||||
* [Server](#server)
|
- [Server](#server)
|
||||||
* [Client](#client)
|
- [Client](#client)
|
||||||
* [Distributed Messaging Architecture](#distributed-messaging-architecture)
|
- [Distributed Messaging Architecture](#distributed-messaging-architecture)
|
||||||
* [Redis Channel Subscriptions](#redis-channel-subscriptions)
|
- [Redis Channel Subscriptions](#redis-channel-subscriptions)
|
||||||
* [Server Configuration](#server-configuration)
|
- [Server Configuration](#server-configuration)
|
||||||
* [Server Publishing](#server-publishing)
|
- [Server Publishing](#server-publishing)
|
||||||
* [Client Usage](#client-usage)
|
- [Client Usage](#client-usage)
|
||||||
* [Metadata](#metadata)
|
- [Metadata](#metadata)
|
||||||
* [Room Metadata](#room-metadata)
|
- [Room Metadata](#room-metadata)
|
||||||
* [Record Subscriptions](#record-subscriptions)
|
- [Record Subscriptions](#record-subscriptions)
|
||||||
* [Server Configuration](#server-configuration-1)
|
- [Server Configuration](#server-configuration-1)
|
||||||
* [Updating Records](#updating-records)
|
- [Updating Records](#updating-records)
|
||||||
* [Client Usage — Full Mode (default)](#client-usage--full-mode-default)
|
- [Client Usage — Full Mode (default)](#client-usage--full-mode-default)
|
||||||
* [Client Usage — Patch Mode](#client-usage--patch-mode)
|
- [Client Usage — Patch Mode](#client-usage--patch-mode)
|
||||||
* [Unsubscribing](#unsubscribing)
|
- [Unsubscribing](#unsubscribing)
|
||||||
* [Versioning and Resync](#versioning-and-resync)
|
- [Versioning and Resync](#versioning-and-resync)
|
||||||
* [Command Middleware](#command-middleware)
|
- [Command Middleware](#command-middleware)
|
||||||
* [Latency Tracking and Connection Liveness](#latency-tracking-and-connection-liveness)
|
- [Latency Tracking and Connection Liveness](#latency-tracking-and-connection-liveness)
|
||||||
* [Server-Side Configuration](#server-side-configuration)
|
- [Server-Side Configuration](#server-side-configuration)
|
||||||
* [Client-Side Configuration](#client-side-configuration)
|
- [Client-Side Configuration](#client-side-configuration)
|
||||||
* [Comparison](#comparison)
|
- [Comparison](#comparison)
|
||||||
|
|
||||||
## Quickstart
|
## Quickstart
|
||||||
|
|
||||||
|
Here's the fastest way to get a server and client connected.
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
@ -40,25 +42,6 @@ const server = new MeshServer({
|
|||||||
server.registerCommand("echo", async (ctx) => {
|
server.registerCommand("echo", async (ctx) => {
|
||||||
return `echo: ${ctx.payload}`;
|
return `echo: ${ctx.payload}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
server.registerCommand("this-command-throws", async (ctx) => {
|
|
||||||
throw new Error("Something went wrong");
|
|
||||||
});
|
|
||||||
|
|
||||||
server.registerCommand("join-room", async (ctx) => {
|
|
||||||
const { roomName } = ctx.payload;
|
|
||||||
await server.addToRoom(roomName, ctx.connection);
|
|
||||||
await server.broadcastRoom(roomName, "user-joined", {
|
|
||||||
roomName,
|
|
||||||
id: ctx.connection.id,
|
|
||||||
});
|
|
||||||
return { success: true };
|
|
||||||
});
|
|
||||||
|
|
||||||
server.registerCommand("broadcast", async (ctx) => {
|
|
||||||
server.broadcast("announcement", ctx.payload);
|
|
||||||
return { sent: true };
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Client
|
### Client
|
||||||
@ -69,39 +52,29 @@ import { MeshClient } from "@prsm/mesh/client";
|
|||||||
const client = new MeshClient("ws://localhost:8080");
|
const client = new MeshClient("ws://localhost:8080");
|
||||||
await client.connect();
|
await client.connect();
|
||||||
|
|
||||||
{
|
const response = await client.command("echo", "Hello!");
|
||||||
const response = await client.command("echo", "Hello, world!");
|
console.log(response); // "echo: Hello!"
|
||||||
console.log(response); // echo: Hello, world!
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Or use the synchronous version which blocks the event loop
|
|
||||||
// until the command is completed.
|
|
||||||
const response = client.commandSync("echo", "Hello, world!");
|
|
||||||
console.log(response); // echo: Hello, world!
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const response = await client.command("this-command-throws");
|
|
||||||
console.log(response); // { error: "Something went wrong" }
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const response = await client.command("join-room", { roomName: "lobby" });
|
|
||||||
console.log(response); // { success: true }
|
|
||||||
}
|
|
||||||
|
|
||||||
client.on("latency", (event) => {
|
|
||||||
console.log(`Latency: ${event.detail.latency}ms`);
|
|
||||||
});
|
|
||||||
|
|
||||||
client.on("user-joined", (event) => {
|
|
||||||
console.log(`User ${event.detail.id} joined ${event.detail.roomName}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.close();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
|
||||||
|
Mesh supports multiple real-time patterns—choose where to go next based on your use case:
|
||||||
|
|
||||||
|
- **Pub/Sub messaging (e.g. chat, notifications):**
|
||||||
|
→ [Redis Channel Subscriptions](#redis-channel-subscriptions)
|
||||||
|
|
||||||
|
- **Granular, versioned data sync (e.g. user profiles, dashboards):**
|
||||||
|
→ [Record Subscriptions](#record-subscriptions)
|
||||||
|
|
||||||
|
- **Identify users, store connection info, or manage rooms:**
|
||||||
|
→ [Metadata](#metadata) and [Room Metadata](#room-metadata)
|
||||||
|
|
||||||
|
- **Control access or validate inputs across commands:**
|
||||||
|
→ [Command Middleware](#command-middleware)
|
||||||
|
|
||||||
|
Want to see how messages flow across servers?
|
||||||
|
→ [Distributed Messaging Architecture](#distributed-messaging-architecture)
|
||||||
|
|
||||||
## Distributed Messaging Architecture
|
## Distributed Messaging Architecture
|
||||||
|
|
||||||
The diagram below illustrates how Mesh handles communication across multiple server instances. It uses Redis to look up which connections belong to a room, determine their host instances, and routes messages accordingly — either locally or via pub/sub.
|
The diagram below illustrates how Mesh handles communication across multiple server instances. It uses Redis to look up which connections belong to a room, determine their host instances, and routes messages accordingly — either locally or via pub/sub.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user