最近开黑啦用户协议的事闹得挺厉害,但据说是从 YY 复制粘贴来的,意思是国内应用是不是都这个德行?我不好评价,所以转头去研究了下 Revolt 搭了个给群友们用。Revolt 是一个开源的类 Discord 社区应用,搭起来坑真是挺多的。年前刚好没什么事,在公司闲着也是闲着,故水文一篇。(时隔两年的新文章……)
Head Pic: #グランブルーファンタジー シンダラちゃん - ねじろ@FANBOX的插画 - pixiv
Revolt
Revolt 是一个开源的类 Discord 社区应用,但毕竟是民间发电,而且项目起步才半年,现阶段跟 Discord 这种商业产品是完全没法比的,未来可期
想搭建的可以试用一下官方 demo 再做决定,因为搭起来还是有点闹心的(特别是语音服务)
主体服务搭建
Revolt 前后端分离,后端包含非常多的小服务,好在官方提供了 docker 部署方式,不然直接就给劝退了
下面说一下部署和配置细节
0. 准备工作
git clone https://github.com/revoltchat/self-hosted revolt --depth=1
cd revolt
cp .env.example .env
然后我们需要按自己需要修改 docker-compose.yml
和 .env
1. docker compose 配置
docker-compose.yml
里面可能需要改的东西只有两个
第一个是端口映射,里面各种服务的 ports
,冒号前面的就是映射到本机的端口,按你的需求自行修改
其中 minio 服务的端口没有在外面被直接使用,都是在 docker 间访问的,因此 minio 的端口是不需要暴露的,直接注释掉都可以
第二个是 mongodb 的版本,mongodb 5 开始要求 CPU 支持 AVX 指令集,如果你的 CPU 支持就不用管,我是在家里的辣鸡小服务器上搭建的,便宜老U不支持 AVX,因此需要改成使用 mongodb 4,把 image 改成 mongo:4.4.12
即可
2. 环境变量配置
要开始改 .env
了,重头戏,需要配合你最终的 nginx 配置来改,这里我先介绍一下需要改动的配置,nginx 部分我会在下一步说
开头糊脸的是一堆需要在外部可以访问到的服务 URL 配置(前端会用到这些 URL),默认的配置是直接按端口分的服务,生产环境下我们需要用子域或路径区分服务,通过 nginx 反代到本地端口
本文示例以子域来区分服务,你也可以用单域名通过路径来区分服务,但后面的 nginx 配置就靠你自己了
# URL to where the Revolt app is publicly accessible (前端)
REVOLT_APP_URL=https://example.com
# URL to where the API is publicly accessible (后端)
REVOLT_PUBLIC_URL=https://api.example.com
VITE_API_URL=https://api.example.com
# URL to where the WebSocket server is publicly accessible (后端 WS)
REVOLT_EXTERNAL_WS_URL=wss://ws.example.com
# URL to where Autumn is publicly available (静态资源服务)
AUTUMN_PUBLIC_URL=https://autumn.example.com
# URL to where January is publicly available (内嵌媒体预览服务)
JANUARY_PUBLIC_URL=https://january.example.com
# URL to where Vortex is publicly available (语音服务)
VOSO_PUBLIC_URL=https://vortex.example.com
VOSO_WS_HOST=wss://vortex.example.com
最后两条是语音服务相关的,需要额外搭建,后面会讲
后面重点需要改的有
REVOLT_INVITE_ONLY
:设置成1
就只有用邀请码才能注册,为了测试方便可以先维持0
,后面会讲怎么生成邀请码(有点麻烦)REVOLT_VAPID_PRIVATE_KEY
&REVOLT_VAPID_PUBLIC_KEY
:看说明自行生成VOSO_MANAGE_TOKEN
:语音服务用的,直接用脸进行一个键盘的滚即可,后面语音服务配置里的 token 要和这里一样
其他的就是例行按你喜好了,Autumn 相关的不需要动
3. nginx 配置
用其它的 web 服务也行,这里用 nginx 示例,正常的部分该怎么配怎么配
map $http_host $revolt_upstream {
example.com http://127.0.0.1:5000;
api.example.com http://127.0.0.1:8000;
ws.example.com http://127.0.0.1:9000;
autumn.example.com http://127.0.0.1:3000;
january.example.com http://127.0.0.1:7000;
vortex.example.com http://127.0.0.1:8080;
}
server {
listen 80;
listen 443 ssl http2;
server_name example.com *.example.com;
# SSL 自己配
if ($http_upgrade) {
# 这里的路径是用来反代 ws 的,脸滚键盘即可,防止和其他服务冲突
rewrite ^(.*)$ /ws_78dd759593f041bc970fd7eef8b0c4af$1;
}
location / {
proxy_pass $revolt_upstream;
proxy_set_header Host $host;
}
location /ws_78dd759593f041bc970fd7eef8b0c4af/ {
# 注意这里的是带尾斜杠的
proxy_pass $revolt_upstream/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
# 重要,防止 ws 长时间不发送数据导致超时断开
proxy_read_timeout 24h;
}
}
这里的端口都是 docker-compose.yml
里默认的端口,另外语音服务 vortex 的默认端口是 8080
,可以改
如果模板配置自带对静态资源的正则 location 啥的记得去掉,不然会把匹配抢掉
4. 启动
ドキドキ时间到了,启动!
docker-compose up -d
该程序没有后台以及超级管理员账户,因此进去后像普通用户一样注册帐号即可,自己对自己创建的频道拥有最高管理权限
注册是有坑点的,我目前发现的有:
- 不能用QQ邮箱注册(果然在国外QQ邮箱都被列为垃圾邮箱了吗,不过我在他们的项目里没有找到黑名单之类的东西,估计是后端用了某个库带的规则)
- 用户名只能英文数字下划线,昵称可以中文,但是没有全局昵称,对每一个频道都得重新设置昵称
停止容器执行
docker-compose stop
销毁容器执行
docker-compose down
如果要改环境变量的话销毁重建
5. 邀请码生成
解决方案来自 revoltchat/revolt#133
简单来说就是你需要手动往数据库里插入邀请码……
首先进入数据库所在容器
docker-compose exec database bash
运行 mongosh,没有的话看后面手动安装
mongosh
然后往集合里插入邀请码
use revolt
db.invites.insertOne({ _id: "邀请码" })
我用的 mongodb 4 的镜像没有 mongosh,因此我手动安装了
apt-get update
apt-get install wget -y
cd ~
wget https://downloads.mongodb.com/compass/mongodb-mongosh_1.1.9_amd64.deb
dpkg -i mongodb-mongosh_1.1.9_amd64.deb
语音服务搭建
1. 编译 vortex
git clone https://github.com/revoltchat/vortex --depth=1
然后修改 Cargo.toml
,在最后加上一行 mediasoup-sys = "0.3.2"
,不加的话会编译错误
之后去安装 rust,具体步骤就不写了跟着官网来就行
开始编译
cargo build --release
编译完的可执行文件在 target/release
里面,拿出来即可
官方在项目里提供了 Dockerfile,但不建议用 docker 跑,因为需要开放非常多的端口供 WebRTC 使用,会有严重的性能问题
2. 启动 vortex
首先需要设置必要的环境变量,环境变量的作用看项目就知道了,下面强调几点
WS_URL
和之前的VOSO_WS_HOST
一致MANAGE_TOKEN
和之前的VOSO_MANAGE_TOKEN
一致- 防火墙记得开放
RTC_MIN_PORT
到RTC_MAX_PORT
之间的端口号 RTC_IPS
的格式是监听IP,宣告IP
,必须是 IP,暂不支持主机名,例如你机器公网 IP 是1.2.3.4
,就填0.0.0.0,1.2.3.4
好了,现在你拥有完全版 revolt 了
后记
坑挺多的,最坑的一点是 nginx 反代 WS
我一开始搭建好的时候,不知道为什么语音持续个一两分钟就会莫名断开,一开始我还以为是服务器问题,但换了好几台都有一样的问题,再后来我去试官方的 demo,却也是好的,我不禁开始怀疑是我的问题
事实证明确实是我的问题,在找朋友一起排查的时候无意中发现语音的 WS 会莫名断开
得知这一关键信息的我终于确定了方向,Google 得知原来还有 proxy_read_timeout
这一设定
nginx 的反代默认读超时是 60s,当 WS 空闲超过这个时间后 nginx 就把连接断开了
API 的 WS 有不停的发心跳包所以幸免于难,但语音的 WS 只有当有人进出或者开闭麦的时候才会传输信息,首当其寄
版权声明:本文为原创文章,版权归 神代綺凜 所有。
本文链接:https://moe.best/tutorial/revolt.html
所有原创文章采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。
Missing WS_URL environment variable.: NotPresent,求解答,谢谢
主要开发者好像是个大二学生,国外的大学生这么夸张的吗。
虽然白嫖限30人
这是什么原因导致的呀
希望可以帮到你
Cargo.toml
不过说实话的,开黑啦出了logo和discord不一样其他地方可以说和discord一模一样,说是完全抄过来的也不为过,所以我才不怎么喜欢用国产软件
现在 tx 也在弄QQ频道了,也是仿 discord 模式不过使用上会更符合国人习惯
期待qq频道,如果能做的比discord更好的话说不定我会去用它