Cerebellum WebSocket Server
This is the Cerebellum WebSocket server designed for realtime applications. The server runs on port 8001.
Getting Started
Setting up your environment
Clone the repo.
Install node dependencies. cd
into the project root and run npm install
.
Create a .env
file in the project root and then copy the content from .env.example
. Fill out the values according to your local development environment.
Running a local development server
- Start running Docker locally.
cd
into the project root and run:
docker compose up --detach
npm run dev
docker compose up --detach
starts running local docker images of Redis and DynamoDB in the background.npm run dev
starts running a local instance of the Cerebellum WebSocket server on port 8001.
Running the server in production
For production, this server is dockerized and its image is used in our AWS CDK infrastructure deployment.
Note: While deploying the AWS infrastructure with the CDK, the environment variables needed for the server will be added automatically during deployment.
Preparing for production
To dockerize this image:
- Run
docker login
to make sure you are logged in to your Dockerhub account. cd
into the project root directory- Create a local Docker image
docker build -t <your-dockerhub-username>/<image-name>:<tag> .
- Push the Docker image to Dockerhub
docker push <your-dockerhub-username>/<image-name>:<tag>
Placing server into production
To use this Docker image in production:
- Install Cerebellum's CLI package globally:
npm install --global @cerebellum/cli
cd
into a folder with no.git
repo- Create the CDK infrastructure deployment folder by running:
cerebellum create
- In the option asking if you want to use your server image, insert the Docker image just created.
For deploying Cerebellum's CDK and more information about our CLI
What's Included
Authentication
Cerebellum's server implements a way to authenticate users before a WebSocket connection is established in order to protect the server. This gives our server protection from unwanted users connecting.
Steps to authenticate:
- Create an API key
- Checkout Cerebellum's CLI for more information on deploying using Cerebellum
- Place the API key into the server
.env
asAPI_KEY=<your_api_key>
- Create a separate authentication server and give it the API key
In practice, this is how authentication works:
- A client attempts to login via a separate authentication server (not Cerebellum's server)
- Once the clients' login is successful, the client is given a JWT token
- The client then gives the JWT token to the Cerebellum server and the Cerebellum server authenticates the JWT token
- Assuming the JWT token was built with the same secret, the user is granted permission to connect to the Cerebellum server via WebSocket
Scalable Realtime Communication
To be able to handle high traffic usage, Cerebellum's server is designed to be easily scalable. To do this, we rely on a Redis cache that will act as a message facilitator between servers. This means that we can horizontally scale (i.e., add more servers) and have a way for all servers to communicate.
Persistent Data Storage Capability
The Cerebellum server is designed to save realtime data to DynamoDB.
- In development mode, data is written directly to a running docker instance of DynamoDB.
- In production mode, the server is designed to send data to a queue.
- Note: An AWS Lambda function will use Dynamoose and send data to the database.
Connection State Recovery
The Cerebellum server is designed to handle dropped connections re-connecting quickly and without re-authentication. We use Socket.io's built-in connection state recovery. The max re-connect timeframe is set to 120 seconds and skip the middleware (which skips authentication).
Realtime Presence
The Cerebellum server is designed for realtime presence. This means that our server gives the capability for users to see realtime updates from other users in their channel. We utilize Redis streams by saving the presence of channels on the Redis temporarily. The server can then implement presence by:
- adding a user to the channel's presence
- removing a user from a channel's presence
- getting all users from a channel's presence
- updating a user's info in the channel's presence
- getting all channels a user is present in
- removing a user from all channel's presence