website/src/content/docs/actors/events.mdx
Events can be sent to clients connected using .connect(). They have no effect on low-level WebSocket connections.
For worked realtime patterns, see the cookbook: Live Cursors and Presence and Chat Room.
Define event names and payload types with events and event<T>(), then use c.broadcast(eventName, ...args) to send events to all connected clients:
Send events to individual connections using conn.send(eventName, ...args):
Send events to all connections except the sender:
<CodeSnippet file="examples/docs/actors-events/send-except-sender.ts" />Clients must establish a connection to receive events from actors. Use .connect() to create a persistent connection, then listen for events.
Use connection.on(eventName, callback) to listen for events:
import { useState } from "react";
import { useActor } from "./rivetkit";
function ChatRoom() {
const [messages, setMessages] = useState<Array<{id: string, userId: string, text: string}>>([]);
const chatRoom = useActor({
name: "chatRoom",
key: ["general"]
});
// Listen for events
chatRoom.useEvent("messageReceived", (message) => {
setMessages(prev => [...prev, message]);
});
// ...rest of component...
}
Use connection.once(eventName, callback) for events that should only trigger once:
import { useState, useEffect } from "react";
import { useActor } from "./rivetkit";
function GameLobby() {
const [gameStarted, setGameStarted] = useState(false);
const gameRoom = useActor({
name: "gameRoom",
key: ["room-456"],
params: {
playerId: "player-789",
role: "player"
}
});
// Listen for game start (only once)
useEffect(() => {
if (!gameRoom.connection) return;
const handleGameStart = () => {
console.log('Game has started!');
setGameStarted(true);
};
gameRoom.connection.once('gameStarted', handleGameStart);
}, [gameRoom.connection]);
// ...rest of component...
}
Use the callback returned from .on() to remove event listeners:
import { useState, useEffect } from "react";
import { useActor } from "./rivetkit";
function ConditionalListener() {
const [isListening, setIsListening] = useState(false);
const [messages, setMessages] = useState<string[]>([]);
const chatRoom = useActor({
name: "chatRoom",
key: ["general"]
});
useEffect(() => {
if (!chatRoom.connection || !isListening) return;
// Add listener
const unsubscribe = chatRoom.connection.on('messageReceived', (message) => {
setMessages(prev => [...prev, message.text]);
});
// Cleanup - remove listener when component unmounts or listening stops
return () => {
unsubscribe();
};
}, [chatRoom.connection, isListening]);
// ...rest of component...
}
GET /inspector/connections shows active connections and connection metadata.GET /inspector/summary provides connections, RPCs, and queue size in one response.For more details on actor connections, including connection lifecycle, authentication, and advanced connection patterns, see the Connections documentation.
RivetEvent - Base event interfaceRivetMessageEvent - Message event typeRivetCloseEvent - Close event typeUniversalEvent - Universal event typeUniversalMessageEvent - Universal message eventUniversalErrorEvent - Universal error eventEventUnsubscribe - Unsubscribe function type