Skip to content

Commit c6a90ad

Browse files
luceosStyleCIBotimorland
authored
feat: donating Realtime to Flarum Foundation (#4295)
* feat: donating Realtime to Flarum Foundation todo: - migrate settings - mark blomstra/realtime as superseded - check js and functionality - optionally add tests * Apply fixes from StyleCI * chore: js changes * chore: continue adapting to framework * chore: update framework composer.json * chore: more framework config * chore: js * chore: format * fix: phpstan (with some cheating - wip) * Apply fixes from StyleCI * fix: serve command not working, add test scaffolding * Apply fixes from StyleCI * chore: autoload-dev * chore: fix typings? * chore: begin refactoing * Apply fixes from StyleCI * chore: cleanup composer.json --------- Co-authored-by: StyleCI Bot <[email protected]> Co-authored-by: IanM <[email protected]> Co-authored-by: IanM <[email protected]>
1 parent dee903f commit c6a90ad

File tree

117 files changed

+8372
-6
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+8372
-6
lines changed

.github/workflows/backend.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ jobs:
88
with:
99
enable_backend_testing: true
1010
backend_directory: .
11-
monorepo_tests: "framework/core extensions/akismet extensions/approval extensions/flags extensions/likes extensions/mentions extensions/nicknames extensions/statistics extensions/sticky extensions/subscriptions extensions/suspend extensions/tags extensions/messages extensions/gdpr php-packages/testing/tests"
11+
monorepo_tests: "framework/core extensions/akismet extensions/approval extensions/flags extensions/likes extensions/mentions extensions/nicknames extensions/statistics extensions/sticky extensions/subscriptions extensions/suspend extensions/tags extensions/messages extensions/gdpr extensions/realtime php-packages/testing/tests"

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@ vendor
33
composer.lock
44
.DS_Store
55
.aider*
6+
Thumbs.db
7+
tests/.phpunit.cache
8+
tests/.phpunit.result.cache
9+
/tests/integration/tmp
10+
.vagrant
11+
.idea/*
12+
.vscode
13+
js/coverage-ts

composer.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"Flarum\\Nicknames\\": "extensions/nicknames/src",
5050
"Flarum\\ExtensionManager\\": "extensions/package-manager/src",
5151
"Flarum\\Pusher\\": "extensions/pusher/src",
52+
"Flarum\\Realtime\\": "extensions/realtime/src",
5253
"Flarum\\Statistics\\": "extensions/statistics/src",
5354
"Flarum\\Sticky\\": "extensions/sticky/src",
5455
"Flarum\\Subscriptions\\": "extensions/subscriptions/src",
@@ -75,6 +76,7 @@
7576
"Flarum\\Nicknames\\Tests\\": "extensions/nicknames/tests",
7677
"Flarum\\ExtensionManager\\Tests\\": "extensions/package-manager/tests",
7778
"Flarum\\Pusher\\Tests\\": "extensions/pusher/tests",
79+
"Flarum\\Realtime\\Tests\\": "extensions/realtime/tests",
7880
"Flarum\\Statistics\\Tests\\": "extensions/statistics/tests",
7981
"Flarum\\Sticky\\Tests\\": "extensions/sticky/tests",
8082
"Flarum\\Subscriptions\\Tests\\": "extensions/subscriptions/tests",
@@ -101,6 +103,7 @@
101103
"flarum/nicknames": "self.version",
102104
"flarum/extension-manager": "self.version",
103105
"flarum/pusher": "self.version",
106+
"flarum/realtime": "self.version",
104107
"flarum/statistics": "self.version",
105108
"flarum/sticky": "self.version",
106109
"flarum/subscriptions": "self.version",
@@ -169,7 +172,8 @@
169172
"symfony/postmark-mailer": "^7.0",
170173
"symfony/translation": "^7.0",
171174
"symfony/yaml": "^7.0",
172-
"wikimedia/less.php": "^4.1"
175+
"wikimedia/less.php": "^4.1",
176+
"plesk/ratchetphp": "v1.0.4"
173177
},
174178
"require-dev": {
175179
"mockery/mockery": "^1.5",
@@ -201,6 +205,7 @@
201205
"extensions/nicknames",
202206
"extensions/package-manager",
203207
"extensions/pusher",
208+
"extensions/realtime",
204209
"extensions/statistics",
205210
"extensions/sticky",
206211
"extensions/subscriptions",

extensions/gdpr/js/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"private": true,
33
"name": "@flarum/gdpr",
4+
"version": "0.0.0",
45
"prettier": "@flarum/prettier-config",
56
"dependencies": {
67
"lodash-es": "^4.17.21",

extensions/gdpr/js/src/forum/components/ProcessErasureRequestModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export interface IProcessErasureRequestModalAttrs extends IInternalModalAttrs {
1616
}
1717

1818
export default class ProcessErasureRequestModal<
19-
CustomAttrs extends IProcessErasureRequestModalAttrs = IProcessErasureRequestModalAttrs
19+
CustomAttrs extends IProcessErasureRequestModalAttrs = IProcessErasureRequestModalAttrs,
2020
> extends FormModal<CustomAttrs> {
2121
comments!: Stream<string>;
2222
loadingAnonymization: boolean = false;

extensions/realtime/.editorconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
root = true
2+
[*]
3+
end_of_line = lf
4+
charset = utf-8
5+
trim_trailing_whitespace = true
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 4
9+
[*.md]
10+
indent_size = 2
11+
trim_trailing_whitespace = false
12+
[{*.js, *.ts, *.jsx, *.tsx}]
13+
indent_size = 2

extensions/realtime/.gitattributes

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.gitattributes export-ignore
2+
.gitignore export-ignore
3+
.gitmodules export-ignore
4+
.travis.yml export-ignore
5+
changelog.md export-ignore
6+
tests export-ignore
7+
phpunit.xml export-ignore
8+
js/*/src export-ignore
9+
js/*/Gulpfile.js
10+
js/*/package.json
11+
js/*/yarn.lock
12+
13+
js/*/dist/*.js -diff

extensions/realtime/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
js/node_modules
2+
js/dist
3+
vendor/
4+
composer.lock

extensions/realtime/.nginx.conf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
location /apps {
2+
proxy_pass http://127.0.0.1:6001;
3+
proxy_set_header Host $host;
4+
proxy_read_timeout 60;
5+
proxy_connect_timeout 60;
6+
proxy_redirect off;
7+
8+
# Allow the use of websockets
9+
proxy_http_version 1.1;
10+
proxy_set_header Upgrade $http_upgrade;
11+
proxy_set_header Connection 'Upgrade';
12+
proxy_set_header Host $host;
13+
proxy_cache_bypass $http_upgrade;
14+
}

extensions/realtime/README.md

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
![](https://extiverse.com/extension/flarum-com/realtime/open-graph-image)
2+
3+
Realtime provides a self-hosted alternative to Pusher with far more features and an active development roadmap. It offers realtime updates of activity on your forum, not just for members but also for guests.
4+
5+
## Features
6+
7+
- Auto update of index (while keeping permissions & subscription states in mind).
8+
- Auto update of notifications (likes, replies, but also for flags).
9+
- New posts pushed into discussions.
10+
- Typing indicator showing the amount of people currently working on a reply in a discussion.
11+
12+
## Requirements
13+
14+
Realtime contains a **service you will need to install** on your hosting environment, similar to the database service (MySQL) or web service (Apache, Nginx). As such you need your own virtual machine, droplet or an environment that allows you to configure scripts to run continuously. In addition, you will need to **run a queue**, we highly recommend the redis queue in combination with realtime.
15+
16+
For this reason this extension isn't likely applicable to anyone hosted on shared hosting environments.
17+
18+
## Premium
19+
20+
This extension requires an active subscription from [flarum.org](https://flarum.org/extension/flarum-com/realtime).
21+
22+
Due to the complexity of this extension we are forced to publish this extension as a paid one. Development and maintenance of these kind of extensions take a massive amount of time. In order to still make Realtime available to as many people as possible, we offer a plan suitable to those who are able to set everything up themselves and a plan for those in need of assistance.
23+
24+
**Important!** There are two tiers of plans for Realtime:
25+
26+
1. Entry edition, [view plan](https://flarum.org/extension/flarum-com/realtime?key=realtime-entry-edition):
27+
- Low cost
28+
- Only for non-profit communities
29+
- No installation assistance
30+
- No expert support
31+
- Single payment, perpetual usage
32+
2. Advanced edition, [view plan](https://flarum.org/extension/flarum-com/realtime?key=realtime-advanced-edition):
33+
- For non-profit and for-profit communities
34+
- Installation assistance up to two hours
35+
- Expert support through email and/or discord
36+
- Yearly subscription
37+
38+
In case you need installation assistance from us directly while on the Entry edition, we will require you to upgrade. Installation assistance and expert support cannot and will not be given on the Entry edition.
39+
40+
Once your subscription is active you can follow the instructions on the [subscriptions page](https://flarum.org/dashboard/subscriptions) to configure composer. Once completed you can run the following command for installation:
41+
42+
```bash
43+
composer remove flarum/pusher
44+
composer require blomstra/realtime:"*"
45+
```
46+
47+
For updates:
48+
49+
```bash
50+
composer require blomstra/realtime:"*"
51+
php flarum migrate
52+
php flarum cache:clear
53+
```
54+
55+
> Managed Flarum communities that we host on our hosting platform ([Blomstra](https://flarum.org/hosting)) have access to all premium extensions by Flarum BV without additional cost.
56+
57+
Enable the extension inside the admin area and follow Set up instructions.
58+
59+
### Set up
60+
61+
**Method a) use the defaults**
62+
63+
No action needed. Your websocket will re-use the configuration of your existing forum.
64+
65+
**Method b) the `config.php`**
66+
67+
Create a key `websocket` and override any of the configuration items:
68+
69+
```php
70+
return [
71+
// ..
72+
'websocket' => [
73+
74+
]
75+
];
76+
```
77+
78+
#### Configuration
79+
80+
All options:
81+
82+
- `server-*`, these options are used for the daemon itself, it specifies what ip/host and port to listen to.
83+
- `server-host` / default(`0.0.0.0`) ; on which host the realtime daemon listens
84+
- `server-port` / default(`6001`) ; on which port the realtime daemon listens
85+
- `js-client-*`, these are used by the Flarum forum frontend (javascript) to connect to the Realtime websocket daemon.
86+
- `js-client-host` / default(config url) ; the host on which the Flarum forum will connect to the websocket server
87+
- `js-client-port` / default(`6001`) ; the port on which the Flarum forum will connect to the websocket server
88+
- `js-client-secure` / default(config url is https then yes, otherwise no) ; whether the Flarum forum will encrypt its connection to the websocket server
89+
- `php-client-*`, when the Flarum backend wants to dispatch events to all users connected to Realtime it will push data to the Realtime daemon with these settings.
90+
- `php-client-host` / default(config url) ; the host to which the Flarum backend will send events
91+
- `php-client-port` / default(`6001`) ; the port to which the Flarum backend will send events
92+
- `php-client-secure` / default(config url is https then yes, otherwise no) ; whether the Flarum backend will communicate encrypted with the Realtime daemon
93+
- `php-client-timeout` / default(`3`) ; when the Flarum backend sends events to the Realtime daemon it will timeout in this number of seconds
94+
- `app-*`, these define the authorization between server, javascript and daemon
95+
- `app-key` / default(hashed version of config url) ; the publicly available key to authenticate with against the Realtime daemon
96+
- `app-secret` / default(hashed version of database password) ; the secret password to grant access to private channels and to dispatch events to the Realtime daemon with
97+
- `max-connections` / default(`1000`), the maximum number of allowed concurrent connections. Reduce this number to lower the strain on your server in case you notice the Realtime daemon being a problem.
98+
99+
100+
### Run the websocket server
101+
102+
For the websocket to run you will need to run its server. To do so for **testing purposes**, use:
103+
104+
```bash
105+
php flarum realtime:serve -vvv --debug
106+
```
107+
108+
This will boot the server and throw any debug information it can. This will keep the server running for as long as you keep this tab/window open.
109+
110+
> The webservice will only run for as long as you keep your window open or your pc on using the above command. Using the realtime service in production requires setting it up as a daemon. See below for instructions for supervisor or systemd.
111+
112+
#### Daemon with supervisor
113+
114+
In production, you will need to set the websocket server to run continuously and restart when it errors. You can use a tool like supervisord for that.
115+
116+
```bash
117+
# On Debian / Ubuntu
118+
apt install supervisor
119+
120+
# On Red Hat / CentOS
121+
yum install supervisor
122+
systemctl enable supervisord
123+
```
124+
125+
Now create a new file inside the `/etc/supervisor/conf.d` directory called `realtime.conf` with:
126+
127+
- `/var/www/flarum` being the path to your Flarum installation, update this under the `command` line.
128+
- `www-data` being the web user that runs your Flarum forum in apache, nginx or other web server software. Update under the `user` line.
129+
130+
```
131+
[program:realtime]
132+
command=/usr/bin/php flarum realtime:serve
133+
directory=/var/www/flarum/
134+
numprocs=1
135+
autostart=true
136+
autorestart=true
137+
user=www-data
138+
stdout_logfile=/var/www/flarum/storage/logs/realtime.log
139+
stderr_logfile=/var/www/flarum/storage/logs/realtime-error.log
140+
```
141+
142+
Now read the configuration file and start the service:
143+
144+
```bash
145+
sudo supervisorctl update
146+
```
147+
148+
Check whether the program is running:
149+
150+
```bash
151+
sudo supervisorctl status
152+
```
153+
154+
More information about supervisor and its commands can be found in their [documentation](http://supervisord.org/running.html#running-supervisorctl).
155+
156+
#### Daemon with systemd
157+
158+
Create a file with vim, vi or another editor of your choice at `/etc/systemd/system/flarum-realtime.service` with these contents:
159+
160+
```
161+
[Unit]
162+
Description=flarum-realtime
163+
StartLimitIntervalSec=0
164+
165+
[Service]
166+
Type=simple
167+
User=www-data
168+
WorkingDirectory=/var/www/flarum
169+
ExecStart=/usr/bin/php flarum realtime:serve
170+
Restart=always
171+
RestartSec=5
172+
173+
[Install]
174+
WantedBy=multi-user.target
175+
```
176+
177+
Make sure to update the `WorkingDirectory` to match the directory where you installed Flarum. Update `ExecStart` to your version of php, you can use `whereis php` or `whereis php80` to seek the path for each php version. Update the `User` to the user your site runs as.
178+
179+
Now reload the systemd service to pick up the service:
180+
181+
```
182+
sudo systemctl daemon-reload
183+
```
184+
185+
Start your service:
186+
187+
```
188+
sudo systemctl start flarum-realtime.service
189+
```
190+
191+
To understand whether it runs:
192+
193+
```
194+
sudo systemctl status flarum-realtime.service
195+
```
196+
197+
Now make sure to automatically start the service on reboots:
198+
199+
```
200+
sudo systemctl enable flarum-realtime.service
201+
```
202+
203+
### Auto restarting
204+
205+
The daemon will halt itself within 10 seconds when it identifies any change in
206+
your extensions. If you en- or disable an extension the daemon will stop.
207+
If properly set up this will allow the
208+
daemon to understand your Flarum changes and operate with the enabled extensions.
209+
210+
You can disable this feature by setting the `--ignore-extension-toggles` flag on the daemon:
211+
212+
```bash
213+
php flarum realtime:serve --ignore-extension-toggles
214+
```
215+
216+
### Manually restarting
217+
218+
In case you want to force a restart within 10 seconds, for instance when using CI/CD, you can use the `realtime:halt` command:
219+
220+
```bash
221+
php flarum realtime:halt
222+
```
223+
224+
### Running encrypted
225+
226+
If you want to run the websocket server encrypted, the easiest way is to proxy the port with your webserver software (apache, nginx).
227+
228+
For **nginx** you can use the provided nginx configuration. Make sure to put the realtime nginx include before your flarum nginx include. Make sure to put both of these at the end of your server block:
229+
230+
```nginx
231+
server {
232+
# your php matching instructions
233+
234+
include /var/www/flarum/vendor/blomstra/realtime/.nginx.conf;
235+
include /var/www/flarum/.nginx.conf;
236+
}
237+
```
238+
239+
> We don't have examples for other webservers yet, but we'll gladly assist you with the installation on the Advanced edition.
240+
241+
**Optional:** to reduce overhead on your community from Flarum trying to interact with a remote url for sending realtime events, we can configure Flarum to use the current server as a target. To do so we can update our Flarum `config.php` like this:
242+
243+
```php
244+
return [
245+
// .. some other instructions
246+
247+
// Make sure the Realtime php client uses localhost instead of the domain
248+
// to reduce latency.
249+
'websocket' => [
250+
'php-client-host' => 'localhost'
251+
]
252+
];
253+
```
254+
255+
256+
### FAQ
257+
258+
*Is Realtime proven?*
259+
The official Flarum community (discuss.flarum.org) has benefited from the features Realtime brings since August 2021. It has also been running on the Blomstra hosting platform since February 2021, most of our managed communities have it enabled.
260+
261+
*How many concurrent users does Realtime support?*
262+
Resource usage of the websocket is really low. You should be able to serve thousands simultaneous users with only 1 cpu and 1 GB of memory dedicated to the process. Once we are able to provide a better indication from usage at scale, we will update this FAQ item. As a general rule of thumb it's always better to oversize your realtime daemon resource limitations and then - based on experience - reduce them to meet actual resource cost.
263+
264+
*SendTriggerJob fails/is killed.*
265+
In case the queue job `SendTriggerJob` fails every single time, make sure to increase the timeout of the queue worker. The default timeout is `60`, also when you leave out the flag, so try running it with `360` like so: `php flarum queue:work --timeout=360`. Read the documentation of your queue driver to understand how to daemonize this command, for testing you can run it in your window with the additional `-vvv` flag for verbose logging.
266+
267+
*I have another question.*
268+
Reach out to us via https://flarum.org/contact/premium-support. We will get back to you as soon as we can. If you have a running subscription please mention when you started your plan and/or which plan you are on. Always add sufficient information when reporting errors. We prefer errors being reported here, but understand that sometimes you can't.
269+
270+
---
271+
272+
- Flarum BV is the commercial companion to the Flarum Foundation.
273+
- https://flarum.org
274+
- https://support.on-flarum.com/t/ext-realtime

0 commit comments

Comments
 (0)