Actionhero ships with a chat framework which may be used by all persistent connections (socket
and websocket
). There are methods to create and manage chat rooms and control the users in those rooms. Chat does not have to be for peer-to-peer communication, and is a metaphor used for many things, including the sharing of all realtime data between client and server, and client to client. This can be used for games, syndication, etc.
Clients themselves interact with rooms via verbs
. Verbs are short-form commands that will attempt to modify the connection's state, either joining or leaving a room. Clients can be in many rooms at once.
Relevant chat verbs are:
roomAdd
roomLeave
roomView
say
The special verb for persistent connections say
makes use of chatRoom.broadcast
to tell a message to all other users in the room, IE: say myRoom Hello World
from a socket client or client.say("myRoom", 'Hello World")
for a websocket.
Chat on multiple Actionhero nodes relies on redis for both chat (pub/sub) and a key store defined by config.redis
. The redis pub/sub server and the key store don't need to be the same instance of redis, but they do need to be the same for all Actionhero servers you are running in the cluster. This is how Actionhero scales the chat features.
There is no limit to the number of rooms which can be created, but keep in mind that each room stores information in redis, and there load created for each connection.
The full documentation for the chatRoom module can be found here: https://docs.actionherojs.com/modules/chatroom.html
In an initializer, ensure a room exists and log the room membership every minute
// in an initializer, /src/initializers/lobby.ts
import { Initializer, chatRoom, log } from "actionhero";
let timer: NodeJS.Timeout;
export class MyInitializer extends Initializer {
constructor() {
super();
this.name = "rooms";
}
async initialize() {
// ensure a room exists
const lobbyExists = await chatRoom.exists("lobby");
if (!lobbyExists) {
await chatRoom.add("lobby");
}
}
async start() {
timer = setInterval(() => {
this.logLobbyStatus();
}, 60 * 1000);
}
async stop() {
if (timer) {
clearInterval(timer);
}
}
async logLobbyStatus() {
const { membersCount } = await chatRoom.roomStatus("lobby");
log(`lobby has ${membersCount} members`);
}
}
And if you want to broadcast a message to all clients in a room, you can use:
// -- client: should either be a real client you are emulating (found in api.connections)
// -- room: is the string name of a room
// -- message: is a string or JSON
chatRoom.broadcast(connection, room, message);
// -- client: `{}` for send to all clients connected
// -- room: is the string name of a room
// -- message: is a string or JSON
chatRoom.broadcast({}, room, message);
There are 4 types of middleware you can install for the chat system: say
, onSayReceive
, join
, and leave
. You can learn more about chat middleware in the middleware section of this site. Using middleware when messages are sent or when connections join rooms is how you build up authentication and more complex workflows.
Every connection object also has a connection.sendMessage(message)
method which you can call directly from the server.
The details of communicating within a chat room are up to each individual server (see websocket).
client.roomAdd(room)
).say
, ie: {client.say('room', Hello World')}
{client.on('say', function(message){ console.log(message); })}
. You can inspect message.room
if you are in more than one room.{{message: "Hello World", room: "SecretRoom", from: "7d419af9-accf-40ac-8d78-9281591dd59e", context: "user", sentAt: 1399437579346}
}If you want to create an authenticated room, there are 2 steps:
join
-style middleware which checks these values. In this middleware, you can determine if the connection should be added to the room or not.The Actionhero server is open source, under the Apache-2 license
Actionhero runs on Linux, OS X, and Windows
You always have access to the Actionhero team via Slack and Github
We provide support for corporate & nonprofit customers starting at a flat rate of $200/hr. Our services include:
We have packages appropriate for all company sizes. Contact us to learn more.
We provide support for corporate & nonprofit customers starting at a flat rate of $200/hr. Our services include:
We have packages appropriate for all company sizes. Contact us to learn more.
For larger customers in need of a support contract, we offer an enterprise plan including everything in the Premium plan plus: