Skip to content

SAMA-Communications/sama-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

579 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SAMA - Simple but Advanced Messaging Alternative - Chat server

Powered by uWebSockets.js

Last commit GitHub issues GitHub stars GitHub license Documentation GitHub language count GitHub top language

NodeJS MongoDB Redis AWS

Screenshot 2022-12-31 at 14 15 04

Motivation

The intention of our messaging protocol and chat server, which are different from others, is to provide an alternative solution to the wide spread XMPP messaging protocol (and to be honest — the only wide spread ‘standard’ these days).

Read complete medium posts Introducing SAMA and What is SAMA about what is SAMA and what problems we are trying to solve with it:

Clients:

Development & Deployment

Local Development / Compete Deployment & E2E Tests

DEMO

The whole SAMA stack can be tested using https://app.samacloud.io public cloud.

Documentation

API reference: https://docs.samacloud.io

Also, there is a set of detailed articles for each API on Medium:

Community and Support

Join our community for support and discussions:

License

GPL-3.0

Help us!

Any thoughts, feedback is welcome! Please create a GitHub issue for any feedback you have.

Want to support us?

Buy Me A Coffee

Node Clustering

What data is stored in Redis by each node ?

sama-node-data

Record key in redis like sama-node-data:{node-endpoint} where {node-endpoint} ws url like ws://192.168.1.13:55495/, so redis record will be sama-node-data:ws://192.168.1.13:55495/. The record is HSET with ttl that equal config value ws.cluster.nodeExpiresIn in seconds + 5 seconds. The record has key/values like ip/port/host etc.

sama-node-users

Record key in redis like sama-node-users:{node-endpoint}. The record is SET that contains list user users connected to this node, user item is string like {organizationId}:{userId}:{deviceId}. Item example: 683db8ecdb9dee54f53304c0:683db9ed29aecb9feb4afb73:38400000-8cf0-11bd-b23e-10b96e40000d

sama-user-devices

Record key in redis like sama-user-devices:{organizationId}:{userId}. The record is SET that contains list user devices ids connected to all nodes. Item example: 38400000-8cf0-11bd-b23e-10b96e40000d

sama-user-data

Record key in redis like sama-user-data:{userId}:{deviceId}. The record in HSET that contains extra user session data e.g. active/inactive status

How nodes discover each other ?

Each node write record key in Redis like sama-node-data:{node-endpoint} where {node-endpoint} it is own ws url. Node create this record on start and update on sync cluster (check method syncCluster). In sync method node retrieve all records from Redis with prefix sama-node-data:, the parse record ws url part ({node-endpoint}) and try establish ws connection if it doesn't already exist.

How nodes connect to each other ?

If node-A does not have establish connection with node-B, node-A will create ws connection (check method createConnectionWithNode). When ws with node-B endpoint (node-endpoint) successfully opened - node-A send like 'ping' message with own network data (ip/port/host etc.) to node-B (check method shareCurrentNodeInfo), node-B send to node-A like 'pong' message with own network data, node-A after receiving 'pong' message - connection successfully established and handshake finished, app resolve promise and save ws connection in local object (check prop clusterNodesConnections). Node-B after send 'pong' message start connecting with node-A by same flow

What happens when connection breaks between 2 nodes ?

If connecting breaks between 2 nodes, node detect it by ws event close, and start reconnecting (check method startNodeReconnecting and promiseQueueWithJittering, prop closeNodesConnections), this method try 3 time create connection until the first successful with delay '1/4/9 seconds', flow like 1 second delay - try connect (if success return) - 4 seconds delay - try connect (if success return) - 9 seconds delay - try connect (if success return) - failed

What happens when new node added to cluster ?

2 Ways (node-A,node-B - running, node-C - new node in cluster)

  • Flow How nodes discover each other and then How nodes connect to each other. Node-C retrieve redis records (sama-node-data) created by node-A,node-B and create ws connections with each node (open ws and then connect flow with 'ping'/'pong').

  • Node-A,node-B in method syncCluster with call with interval that equal config value ws.cluster.nodeExpiresIn in ms, retrieve sama-node-data records and see new node record created by node-C and then create connection with node-C

What happens when existing node removed from cluster ?

Example with node-A and node-B

When node-B disconnect from cluster, ws connection breaks and node-A start reconnecting with node-B but it will not be success. Then on next syncCluster iteration (or next + 1 iteration) node-A can't find node-B record in sama-node-data records, but has active reconnecting state with node-B, then mean that node-B destroyed because no-one update node-B sama-node-data record ttl, then node-A cancel reconnecting and clean redis data creates by node-B (sama-node-users/sama-user-devices/sama-user-data), sama-node-data already deleted by redis ttl.

Conditions when node mark other nodes like destroyed and should clean data ?

It can be detected no syncCluster iteration

  • If have active node record sama-node-users w/o ttl, but do not have record sama-node-data - no-one update record so node is destroyed
  • If do not have node record sama-node-data but has reconnecting state
  • If have connection (check prop clusterNodesConnections) but do not have record sama-node-data (case when some how ws close was not called)

How its data is cleared from Redis ?

Check method cleanDestroyedNodeData that clean destroyed node data by node-endpoint. Flow:

  • retrieve sama-node-users - list of user who was connected to destroyed node
  • delete 'smembers' from sama-user-devices
  • delete sama-user-data record
  • delete sama-node-users

About

SAMA - Simple but Advanced Messaging Alternative chat server, powered by uWebsockets.js

Topics

Resources

License

Stars

158 stars

Watchers

4 watching

Forks

Packages

 
 
 

Contributors