Skip to main content
Version: 0.10

Realtime

Create live and event-driven custom posts.

note

This is an experimental feature that currently only works on Web clients, Mobile support is coming soon. Developer experience may change significantly prior to GA.

Realtime provides a set of primitives that lets you build custom posts that are:

  • Live. Users engaging with the same custom post see each others’ changes without any observable lag.
  • Event-driven. Posts render automatically in response to server events.
  • Synced. Using realtime with Redis lets you build persistent community experiences that are backed by high performance data synchronization.

Create a live custom post

1. Configure realtime.

Devvit.configure({
realtime: true,
});

2. Create and subscribe to a channel.

useChannel hook allows custom posts to subscribe and send to an event stream.

// Defined within render function of a custom post

const { useState, useChannel, redis, ui } = context;

A new channel can be setup with function handlers containing custom logic to update state:

  • onMessage - called every time a message is received on a channel
  • onSubscribed - optional hook to be informed when channel has connected
  • onUnSubscribed - optional hook to be informed when channel has disconnected
// Defined within render function of a custom post

// Choose a channel name that works for you

// You have the flexibility to define the message data shape to be published
// via channel.send - same shape will be received in the onMessage handler

const channel = useChannel({
name: 'events',
onMessage: (data) => {
// modify local state
},
onSubscribed: () => {
// handle connection setup
},
onUnSubscribed: () => {
// handle network degradation with fallback scenarios
},
});

// subscribe to the channel to receive messages
channel.subscribe();

3. Send messages to a channel.

channel.send is recommended for peer-to-peer synchronization across clients. See Mini Place and Snoo Club

<button
icon="add-fill"
width={50}
onPress={async () => {
const newProgress = Math.max(progress + 10, 0);
const message: RealtimeMessage = {
payload: { progress: newProgress },
session: UUID,
};
setProgress(newProgress); // set local state
await channel.send(message); // publish message to the channel
}}
/>

realtime.send is recommended for re-rendering custom posts based on server events. This can be invoked on an event trigger, scheduled job or after a HTTP fetch call. Server-Push example illustrates how to compose scheduler and realtime together.


// During app installation, we create a scheduled job 'publish_to_channel' that runs
// every minute - it uses realtime plugin to publish events to an arbitary channel

Devvit.addTrigger(
event: 'AppInstall',
onEvent: async (_, { scheduler }) => {
await scheduler.runJob({
name: 'publish_to_channel',
cron: '* * * * *'
})
},
});

// Custom posts subscribed to the 'events' channel via useChannel hook will start
// receiving messages which can processed in the onMessage handler to update local state.
Devvit.addSchedulerJob({
name:'publish_to_channel',
onRun: async (_, { realtime, postId }) => {
await realtime.send(
'events',
{
'message': payload
}
);
},
});

Limits and Quotas

  • Messages/sec per installation: 100
  • Maximum message payload: 1 MB
  • Channels per app installation: 5

Examples

note

Try the demos with multiple browser windows and see local changes sync across sessions without any lag.

Mini Place

mini_place_high

Demo, Source Code

Snoo Club

snoo_club

Demo, Source Code

Synced Progress Bar

synced_progress_bar

Demo, Source Code

Devvit Emoji Chat

devvit_emoji_chat

Demo, Source Code

Server Push

server_push

Demo, Source Code