Skip to content
This repository has been archived by the owner on Nov 10, 2022. It is now read-only.

Introduce channels, groups and user tracking in websocket. Scale horizontally using redis as publish-subscribe

Notifications You must be signed in to change notification settings

alessandro-caldonazzi/ws-redis

Repository files navigation

ws-redis

Build Status Codacy Badge

Node.js module that simplifies websocket usage introducing channels, groups and tracking users.

Also, it allows you to use redis as a publish - subscribe for websocket message delivery.

It is divided into a server library and a client library

Complete Docs

In this readme you will find an introduction, you can read the specific documentation here

Server Library

Installation

npm i ws-redis
const wsRedis = require("ws-redis");
const ws = require("ws");

wsRedis.init(new ws.Server({ port: 8080 }));

Sets the callback to be called when a user logs on

wsRedis.onConnection((wsInstance, authenticationToken) => {
    //authenticationToken is a optional token set by client,
    //if present, it means that the user has already been authenticated, so there is no need to check the authenticationToken here.
});

Sets a callback to validate the authenticationToken set by the client (optional).

The callback you set must return true if the authenticationToken is valid, and can be an async function.

wsRedis.checkAuthentication((authenticationToken) =>{
    if(/* authenticationToken is valid */){
        return true;
    }
    return false;
});

You can identify a user with a string at any time, for example during connection.

wsRedis.onConnection((wsInstance, authenticationToken) => {
    wsRedis.addUser("userName", wsInstance);
    //from now on you can refer to the user by his identifier
});

You can also group users into groups, e.g. to send a broadcast message to all of them.

wsRedis.onConnection((wsInstance, authenticationToken) => {
    wsRedis.addToGroup("groupName", wsInstance);
});

Messages are sent/received on channels, you have to manage messages coming from different channels separately.

wsRedis.onMessage("channelName", (message, wsInstance, userIdentifier) => {
    console.log(message);
    //wsInstance can be used to add the user to a group for example

    //If you have added the user with the addUser() method, userIdentifier will show you the identifier of the user who sent the message
    console.log(userIdentifier); //identifier set in addUser()
});

To send a message you have to specify the user identifier (set in addUser()), the channel and the message to be sent, you can also pass a JSON

wsRedis.sendMessageToUser("userName", "channelName", "data I want to send");

If you have set up redis, in case the specified user is not on this node server, it will be sent from the node instance that owns that user

wsRedis.sendMessageToGroup("groupName", "channelName", "data I want to send");

When a client disconnects with the close() method or due to connection problems, a callback (if set) is called on the server to notify you of the incident

wsRedis.onClientClosed((userIdentifier, groups) => {
    //userIdentifier of the disconnected user
    //groups is a string Array, contains the identifier of the groups in which the user participated
});

The client can be used either on node with the ws library or on a browser. If you are on browser you can include it from cdn:

<script
    src="https://cdn.jsdelivr.net/gh/alessandro-caldonazzi/ws-redis/src/client/client.js"
    defer
></script>

Initiate

If you are on browser use WebSocket

const connection = new WsClient({
    url: "ws://x.y:8080",
    websocket: WebSocket,
});
connection.connect();

If you are on nodejs use the ws library

const WebSocket = require("ws");
const connection = new WsClient({
    url: "ws://x.y:8080",
    websocket: WebSocket,
    authenticationToken: "jwt for example", // this is optional, use this if you need authentication (remember to set the checkAuthentication callback on server)
});
connection.connect();

To start the ws connection you need to call connect() Returns a promise, if you need to wait for a successful connection with await

connection.connect();
await connection.connect();
connection.onMessage("channelName", (data) => {
    console.log(data);
});
connection.send("channelName", "your data");

Data can be JSON

Set a callback to be notified when connection fail (for example connection instability)

connection.onConnectionFailure(() => {
    console.warn("connection lost");
});

Set a callback to be notified when the connection is re-established

connection.onConnectionReestablished(() => {
    console.log("connection re-established");
});

About

Introduce channels, groups and user tracking in websocket. Scale horizontally using redis as publish-subscribe

Topics

Resources

Stars

Watchers

Forks