Skip to content

Add an admin guide for the bundled Realtime extension - #598

Merged
imorland merged 2 commits into
flarum:mainfrom
karl-bullock:docs-realtime-admin-guide
Oct 4, 2026
Merged

imorland merged 2 commits into
flarum:mainfrom
karl-bullock:docs-realtime-admin-guide

Conversation

@karl-bullock

Copy link
Copy Markdown
Member

Closes the gap I raised in #593. Realtime is bundled in 2.0 and has no admin-facing documentation on this site at all, while being the one bundled extension that cannot simply be switched on.

I offered in #593 to wait for a decision on the shape of this. Given where 2.0 is, a draft you can correct seemed more useful than an unanswered question, so here is one. Push back freely on structure or placement.

Why it needs a page rather than a paragraph

Realtime requires a supervised long-running daemon and a queue worker. Enabling it without either leaves the forum working perfectly normally, with none of the realtime behaviour happening, and nothing anywhere to explain why. That is a bad first experience with a headline feature, and the information to avoid it currently lives only in the extension's README.

What the page covers

What it does, the requirements including the shared-hosting caveat, enabling it, realtime:serve for testing, supervising the daemon with either supervisor or systemd, the websocket block in config.php with every option and its real default, terminating TLS by proxying with nginx, the ten-second self-halt on extension toggles plus --ignore-extension-toggles and realtime:halt, and troubleshooting through realtime:info and the SendTriggerJob queue timeout.

It is added to the Bundled Extensions sidebar category, which until now contained only extensions/audit, and follows that page's shape. It cross-references the Realtime extender for developers rather than duplicating it.

Sourced from the code, not just the README

The README was the starting point, but every default in the options table comes from Flarum\Realtime\Websocket\Settings::defaults(), and the command options from ServeCommand, HaltCommand and InfoCommand. Three things came out of that which the README does not say, or says wrongly:

  • The nginx include path is corrected. The README says vendor/blomstra/realtime/.nginx.conf, which dates from before the extension was bundled. The package is flarum/realtime and ships its own .nginx.conf, so the documented path is vendor/flarum/realtime/.nginx.conf. Anyone following the README today gets a config that does not resolve. Worth fixing in the README too, which I have not touched here.
  • app-key and app-secret defaults are explained, with a suggestion to override them. They derive from the forum's hostname and an MD5 of the database password respectively. That works, but it means the websocket secret silently changes if the database password is ever rotated, so the page suggests setting both explicitly.
  • The nginx include ordering is explained rather than just asserted. The realtime include has to come before Flarum's, because Flarum's catch-all would otherwise swallow the websocket path. Knowing why makes it much harder to get wrong.

I also verified the queue requirement is real rather than advisory: SendTriggerJob is a genuine queued job, so on the default sync driver every push would run inside the web request that triggered it.

Verification

npx docusaurus build --locale en completes with no errors, the page renders, Docusaurus reports no broken anchors on it, and the sidebar resolves with no dangling entries.

Still open, and not for me to answer

#593 also notes that console.md omits the three realtime commands. I left them out of #595 deliberately so that they can live with this page instead, but if you would rather they also appear in the command reference, say so and I will add them.

The remaining 21 bundled extensions still have no user-facing page. That is a much bigger question than this PR and I have not assumed an answer to it.

Realtime is bundled in 2.0 but had no admin-facing documentation at all. Unlike the other bundled extensions it is not just an enable switch: it needs a supervised long-running daemon and a queue worker, and enabling it without those leaves the forum working normally with none of the realtime behaviour happening and nothing to explain why. Everything an admin needed was in the extension's README, which is not published anywhere.

The page covers what it does, the requirements and the shared-hosting caveat, enabling it, running realtime:serve for testing and supervising it with either supervisor or systemd, the websocket block in config.php with every option and its real default, terminating TLS by proxying with nginx, the ten-second self-halt on extension toggles plus --ignore-extension-toggles and realtime:halt, and troubleshooting via realtime:info and the SendTriggerJob queue timeout.

Defaults come from Flarum\Realtime\Websocket\Settings rather than from the README, and the command options from the command classes. The nginx include path is corrected to vendor/flarum/realtime/.nginx.conf: the README still says vendor/blomstra/realtime, from before the extension was bundled, which would not resolve for anyone following it.

Two things the README does not say are called out. app-key and app-secret default to values derived from the forum host and the database password, so the page suggests setting them explicitly rather than having the websocket secret change with a database password. And the ordering requirement on the two nginx includes is explained rather than just stated, since Flarum's own config has the catch-all that would otherwise swallow the websocket path.

Refs flarum#593.
I documented realtime:info as printing the settings the daemon is using. Running it on a Flarum 2.0.0-rc.8 instance shows it does something else, and something more useful: it lists the open channels, counts connected signed-in members, then fires three test events, one direct, one async, and one through the queue.

That distinction is worth spelling out, because the three outcomes separate the failure modes the rest of the page warns about. Direct and async succeeding proves the backend can reach the daemon and the php-client settings are right; only the queued one failing points at the queue worker rather than at realtime; none of them succeeding means the daemon is unreachable from PHP.
@karl-bullock

Copy link
Copy Markdown
Member Author

Corrected one thing here after running it on a Flarum 2.0.0-rc.8 instance, now pushed.

I had described realtime:info as printing the settings the daemon is using. It does something else, and something more useful: it lists the currently open channels, counts connected signed-in members, and then fires three test events, one direct, one asynchronous, and one through the queue.

That is worth spelling out rather than glossing, because the three outcomes separate exactly the failure modes the rest of the page warns about:

  • direct and async both succeed: the backend can reach the daemon, so the php-client-* settings and the daemon are fine
  • those two succeed but the queued one never arrives: the problem is the queue worker, not realtime
  • none succeed: the daemon is not reachable from PHP at all

The page now says that, and the "nothing updates, and no errors" entry points at it.

The rest held up: realtime:serve, realtime:halt and realtime:info are all registered, and SendTriggerJob really does go through the queue, which is what makes the third test event a meaningful signal.

@imorland
imorland merged commit 16c9ffe into flarum:main Oct 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants