Peerloom:搭个在线协作室

十一假期,给自己折腾了一个在线协作工具:Peerloom

十一放假,终于可以休息几天。作为一个程序员,这时候应该做点什么呢?我决定:卷起来。毕竟,头发卷起来,显得发量多。于是,趁着假期折腾了一下,把一个屏幕共享工具慢慢改成了现在的 Peerloom:打开浏览器,建一个房间,就能共享屏幕、语音聊天、一起写文档、画白板,还能一起看本地视频。假期有没有得到充分休息不好说,工具栏倒是比放假前充实了不少。

打开浏览器,进入同一个房间,就能共享屏幕、语音聊天、一起写文档、画白板,还能一起看本地视频。
它基于开源项目 Screego 二次开发。我在屏幕共享的基础上,补充了一些讨论时常用的功能,以及中文操作界面。
想解决的事情很简单:几个人临时聚在一起,看同一块屏幕,把问题聊明白,顺手记下结论。
至于为什么放假还在写代码——可能程序员的休息,就是换一个自己愿意修的 Bug。
这篇主要介绍两件事:怎么部署,以及部署好以后怎么用。 没接触过这个项目,也可以跟着步骤来。

01 · 先看看,它能做什么

功能 可以用来做什么
屏幕共享 展示代码、网页、软件操作和运行结果
语音与摄像头 一边看画面,一边讨论
协作文档 共同整理笔记、讨论结论和待办
协同白板 画草图、理流程、解释思路
本地音视频同播 一起查看视频素材、观看演示或收听音频
房间管理 管理成员、控制媒体权限、查看连接状态
自托管 部署到自己的服务器,按需设置容量

进入房间后,主区域用于展示共享画面,右侧可以查看成员信息、媒体席位和房间聊天。

Peerloom 房间界面:共享区域、成员信息和房间聊天

界面截图:尚未开启画面共享时,主区域显示“暂无视频流”,这是正常的等待状态。截图中的容量以演示环境配置为准。

比如远程讨论一个页面,可以先共享屏幕说明问题,再打开白板画调整思路,最后把结论写进协作文档。

大家围绕同一个房间协作,少一些软件切换,也少一些“刚才那个链接再发一下”。

02 · 部署之前,需要准备什么

部署路线:准备环境、构建、配置账号、启动、公网访问与长期运行

部署路线示意:先看整体步骤,再按下面的命令逐项完成。

普通使用者只需要浏览器。只有负责部署的人,才需要准备服务器和安装构建工具。

下面的命令以 Linux 服务器为主,使用源码构建方式。建议直接在准备运行 Peerloom 的服务器上编译,避免把其他系统生成的程序拿过来运行。

需要准备:

准备项 用途
Linux 服务器 运行 Peerloom
Git 下载项目源码
Go 1.26.0 或更高版本 编译后端程序
Node.js、Yarn 安装依赖并构建网页界面
域名和 HTTPS 证书 供其他人通过浏览器安全访问
可配置的防火墙或安全组 放通网页和音视频连接需要的端口

Node.js 版本需要满足项目当前前端依赖的要求,具体以仓库说明为准。

安装好工具后,可以先在终端检查:

git --version
go version
node --version
yarn --version

如果提示 command not found,说明对应工具尚未安装,或者没有加入系统命令路径,需要先完成这一步。

后面的命令默认在项目目录中执行。代码框里的内容可以复制到终端;其中的服务器 IP、域名和文件路径,需要换成自己的实际值。

03 · 下载代码,生成可运行的程序

先下载项目:

git clone https://github.com/eson-sheng/peerloom.git
cd peerloom

第一条命令会创建一个 peerloom 文件夹,第二条命令进入这个文件夹。

接着下载后端依赖:

go mod download

安装并构建前端:

(cd ui && yarn install --frozen-lockfile)
(cd ui && yarn build)

这里的括号表示临时进入 ui 目录执行命令,完成后仍回到原来的项目目录。

最后编译后端:

go build \
  -ldflags "-X main.version=1.0.0 -X main.mode=prod" \
  -o peerloom ./main.go

编译完成后,当前目录里会生成一个名为 peerloom 的可执行文件。

检查它能否正常运行:

./peerloom --version

简单解释一下:

  • ./peerloom:运行当前目录里的 Peerloom 程序。
  • --version:查看程序版本。
  • main.version=1.0.0:设置这次构建显示的版本号。
  • main.mode=prod:使用生产模式,避免加载开发环境专用配置。

构建顺序不能颠倒:先构建前端,再编译 Go 程序。

因为生产构建会把前端资源一起放进可执行文件里。以后修改了网页界面,也需要重新构建前端、重新编译程序,才能更新部署后的页面。

每条命令都应成功完成后再执行下一条。遇到报错先处理,不要一路复制到底,最后期待奇迹发生。

04 · 创建配置文件,告诉程序怎么运行

首次部署时,复制一份示例配置:

cp peerloom.config.example peerloom.config.local

这条命令的意思是:保留原来的示例文件,再生成一份自己的配置文件。

已经部署过的朋友,直接编辑现有的 peerloom.config.local,不要重复复制覆盖。

先生成一个随机密钥:

openssl rand -hex 32

终端会输出一长串字符,把它保存下来,稍后填入 PEERLOOM_SECRET。

这个密钥用于登录会话,不是网页登录密码。设置后保持固定,不要每次启动都重新生成。

使用文本编辑器打开配置文件,例如:

nano peerloom.config.local

如果使用 nano,编辑后按 Ctrl + O 保存,按回车确认文件名,再按 Ctrl + X 退出。

把下面这些配置项修改为自己的值,其他项目暂时保留示例中的设置:

# 服务器对访问者可达的 IP,公网部署填写公网 IP
PEERLOOM_EXTERNAL_IP=YOUR_SERVER_IP

# 填入刚才生成的随机密钥
PEERLOOM_SECRET=YOUR_RANDOM_SECRET

# 网页服务监听地址
PEERLOOM_SERVER_ADDRESS=0.0.0.0:5050

# 内置 TURN 服务监听地址
PEERLOOM_TURN_ADDRESS=0.0.0.0:3478

# TURN 中继使用的 UDP 端口范围
PEERLOOM_TURN_PORT_RANGE=50000:50100

PEERLOOM_AUTH_MODE=turn

# 账号文件的绝对路径,下一节会创建
PEERLOOM_USERS_FILE=/absolute/path/to/peerloom/users.local

# 每个房间最多 12 人
PEERLOOM_MAX_ROOM_MEMBERS=12

# 最多 6 个实时媒体席位
PEERLOOM_MAX_MEDIA_SEATS=6

其中,有几个地方需要特别说明。

服务器 IP 怎么填?

公网部署填写客户端能够访问到的服务器公网 IP;局域网部署填写其他设备能够访问到的局域网 IP。

这里填写的是 IP,不是 https://你的域名,也不是网页端口。

账号文件路径怎么找?

在项目目录执行:

pwd

假设输出:

/home/ubuntu/peerloom

那么账号文件路径就填写:

PEERLOOM_USERS_FILE=/home/ubuntu/peerloom/users.local

/absolute/path/to/peerloom/users.local 只是示意,不能原样照抄。

12 人和 6 个媒体席位有什么区别?

12 人是房间总人数上限;6 个媒体席位限制同时发布屏幕、摄像头或同播内容的人数。

语音独立于这些内容席位,但仍受房主设置的媒体权限控制。媒体席位数不能超过房间人数。

配置文件放在哪里?

按本文命令生成的生产程序,会优先读取可执行文件同目录下的 peerloom.config.local。系统环境变量的优先级更高。

修改配置后,需要重启 Peerloom 才能生效。

05 · 创建账号:把这条命令讲清楚

首次创建账号文件,执行:

./peerloom hash --name admin > users.local

账号命令拆解:运行程序、生成密码哈希和写入文件

命令说明示意:首次创建用 >,新增账号用 >>;账号文件修改后需要重启服务。

这条命令看起来短,里面其实有四件事:

部分 含义
./peerloom 运行当前目录里的程序
hash 生成密码哈希,也就是用于验证密码的记录
--name admin 指定用户名为 admin
> users.local 把生成的账号记录写入文件

执行后,终端会提示:

Enter Password:

输入你准备使用的登录密码,然后按回车。

输入时不会显示字符,也不会显示星号,这是正常现象。 不用怀疑键盘,更不用多按几遍。

完成后,账号记录会写入 users.local。因为结果已经写进文件,所以终端没有再显示一大段内容也是正常的。

以后网页登录时使用:

  • 用户名:admin
  • 密码:刚才输入的密码

文件里保存的是密码哈希,不是明文密码。登录时填写自己设置的原始密码,不要复制文件中的哈希字符串。

另外,admin 只是示例用户名,这个名字本身不会赋予额外的系统管理员权限。你也可以改成:

./peerloom hash --name eson > users.local

上面两条首次创建命令选一条执行即可。

新增第二个账号

如果账号文件已经存在,希望再添加一个用户,应使用两个大于号:

./peerloom hash --name alice >> users.local

再根据提示输入 Alice 的密码即可。新增用户名应与现有账号不同。

这里一定要分清:

符号 效果
> 覆盖文件,原有内容会被清空
>> 在文件末尾追加,保留原有内容

首次创建用 >,新增账号用 >>。

少一个大于号,可能就把同事的账号一起“优化”掉了。

修改密码

当前通过账号文件维护用户。修改密码时,可以先备份:

cp users.local users.local.bak

然后为指定用户生成新的账号记录:

./peerloom hash --name admin

输入新密码后,终端会输出一整行新的记录。

打开 users.local:

nano users.local

找到以 admin: 开头的那一行,用刚生成的完整记录替换它,然后保存。

只替换目标用户那一行,保留其他账号。修改完毕后重启服务。

删除账号

同样先备份文件,再删除该用户对应的一整行,保存后重启。

账号文件在服务启动时读取,所以新增账号、修改密码和删除账号,都需要重启才能重新加载。重启也会影响正在进行的房间会话,尽量在没人使用时操作。

账号和访客有什么关系?

按照本文配置:

  • 有账号的人登录后可以创建房间。
  • 朋友收到房间链接后,可以以访客身份加入已经存在的房间。
  • 不存在的房间不会因为访客打开链接就自动创建。

因此,不需要为每位临时参加讨论的朋友都创建账号。

06 · 启动服务,先确认程序跑起来

在项目目录运行:

./peerloom serve

serve 的意思是启动服务,开始接受浏览器连接。

如果配置正确,程序会持续运行,并在终端输出日志。

终端没有回到命令输入状态,不是卡住了,而是服务正在工作。

如果 Peerloom 就运行在你的电脑上,可以访问:

http://localhost:5050

如果程序运行在远程服务器上,你电脑里的 localhost 指的是你自己的电脑。远程使用需要访问服务器地址,正式使用则应配置下一节介绍的 HTTPS 域名。

此时按 Ctrl + C 可以停止服务。

这种启动方式适合首次检查。关闭终端或断开连接后,服务可能随之停止;需要长期运行时,再配置后面的后台服务。

07 · 公网访问:网页和音视频都要打通

让朋友通过互联网使用,还需要完成三件事:

  1. 将域名解析到服务器。
  2. 配置 HTTPS 和网页反向代理。
  3. 放通 TURN 和中继端口。

公网网络示意:HTTPS 网页连接和 WebRTC、TURN 媒体传输

网络示意:网页走 HTTPS 和 WebSocket,媒体尝试直连,必要时通过 TURN 中继。

先配置域名和 HTTPS

例如准备使用:

https://meet.example.com

先在域名服务商处添加解析,让该域名指向服务器公网 IP,然后在服务器上配置对应的 HTTPS 证书。

浏览器使用屏幕共享、麦克风和摄像头等功能需要安全上下文。正式远程使用应配置 HTTPS,不要只停留在“公网 IP 加 HTTP 端口能打开页面”这一步。

如果通过服务器面板部署,可以创建网站、绑定域名、申请证书,并把反向代理目标设置为:

http://127.0.0.1:5050

这里假设反向代理和 Peerloom 运行在同一台服务器上。

反向代理要支持 WebSocket

Peerloom 的 /stream 连接需要支持 WebSocket。

如果使用 Nginx,可以在已经配置好域名和证书的 HTTPS server 块中,加入或调整下面的代理配置:

location / {
    proxy_pass http://127.0.0.1:5050;
    proxy_http_version 1.1;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    proxy_read_timeout 3600s;
}

这是代理部分的示例,不是包含证书设置的完整 Nginx 配置文件。使用面板时,应按面板提供的反向代理和 WebSocket 设置填写。

再放通网络端口

按照前面的配置,需要检查:

端口 协议 用途
443 TCP HTTPS 网页访问
80 TCP 按证书签发、HTTP 跳转方案需要开放
3478 TCP、UDP 内置 TURN 服务
50000–50100 UDP 本文示例设置的 TURN 中继端口范围

如果云服务器有安全组,同时系统启用了防火墙,需要两边都允许对应流量。

5050 是 Peerloom 网页服务端口。同机反向代理通过它连接程序时,通常不需要向公网开放;也可以将程序监听地址改为 127.0.0.1:5050,仅供同机代理访问。

如果服务器位于路由器后面,还需要配置相应端口映射。

特别注意:普通 HTTP 反向代理只能处理网页相关流量,不能代替 TURN 转发。

所以,“页面能打开,但别人看不到共享画面”,完全可能发生。网页和音视频需要分别验证。

08 · 让它在后台长期运行

首次启动检查通过后,Linux 服务器可以使用 systemd 管理 Peerloom,实现开机启动和进程异常退出后的自动重启。

下面假设:

  • 程序目录是 /home/ubuntu/peerloom
  • 运行账号是 ubuntu
  • 服务器使用 systemd

请按实际情况修改路径和用户名,并确保该用户能读取配置与账号文件、执行程序。

如果之前还在终端运行 ./peerloom serve,先按 Ctrl + C 停止,避免两个进程争用端口。

创建服务文件:

sudo nano /etc/systemd/system/peerloom.service

写入:

[Unit]
Description=Peerloom collaboration server
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/peerloom
ExecStart=/home/ubuntu/peerloom/peerloom serve
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

保存后执行:

sudo systemctl daemon-reload
sudo systemctl enable --now peerloom

第一条让 systemd 读取新配置,第二条启动服务并设置开机自动启动。

以后常用的命令如下:

# 查看运行状态
sudo systemctl status peerloom

# 重启服务:修改配置或账号后使用
sudo systemctl restart peerloom

# 停止服务
sudo systemctl stop peerloom

# 持续查看日志
sudo journalctl -u peerloom -f

查看日志时按 Ctrl + C,只是退出日志查看,不会停止后台服务。

至此,服务器终于可以自己上班了。

09 · 部署好了,怎么使用?

可以先用两台设备做一次完整测试:一台创建房间,另一台通过链接加入,再验证语音和画面。

第一步:登录并创建房间

打开部署好的 HTTPS 地址,使用前面创建的账号登录。

Peerloom 登录界面

登录页实拍:输入通过 hash 命令创建的用户名和密码。截图未填写登录信息。

例如:

用户名:admin
密码:运行 hash 命令时设置的密码

按页面提示填写房间信息并创建。

Peerloom 创建房间界面

创建房间实拍:填写房间号,并确认“你离开后关闭房间”选项。

创建时注意“房主离开时关闭房间”相关选项。如果启用,房主离开会影响房间里其他成员继续使用。

第二步:邀请朋友

创建成功后,将房间链接发给朋友。

对方打开链接,按页面提示填写昵称,即可作为访客加入已有房间。

如果提示房间不存在,请先确认房主已经创建房间,且房间尚未关闭。

Peerloom 房间成员列表与操作工具栏

成员列表实拍:展开右侧成员列表可以查看身份和在线状态;下方工具栏提供各项协作入口。

第三步:开启语音

通过工具栏开启麦克风,浏览器弹出权限请求时选择允许,并确认使用了正确的输入设备。

两台设备放在同一个房间测试时,建议佩戴耳机,避免声音来回播放产生回声。

第四步:共享屏幕

点击屏幕共享入口,浏览器会让你选择共享内容,例如整个屏幕、某个窗口或浏览器标签页。具体选项取决于浏览器和系统。

选中内容后确认共享,其他成员就可以在房间里看到画面。

结束时点击停止共享。语音与内容共享分开处理,结束画面共享后,仍可以继续聊天。

摄像头也可以通过工具栏开启。不过,同一位成员同时只能发布屏幕、摄像头或同播中的一种内容,切换时先结束当前内容。

Peerloom 共享设置界面

设置面板实拍:可以查看首选编码、显示模式和帧率。初次使用可先保留默认设置。

第五步:一起写文档、画白板

打开“协作文档”,即可共同编辑房间里的文档。

Peerloom 协作文档:共同整理讨论目标、安排和待办

界面截图:协作文档示例。上方是格式工具栏,下方可以共同整理讨论目标、安排和下一步事项。

可以记录:

  • 本次讨论的目标。
  • 发现的问题。
  • 确认的解决方案。
  • 接下来由谁做什么。

编辑器支持标题、加粗、斜体、列表、待办、引用和代码块等常用格式。

需要画流程、解释页面布局或梳理关系时,再打开协同白板。

Peerloom 协同白板中实际绘制的页面草图

白板实拍:在演示站用画笔绘制页面布局和确认流程,上方提供颜色、粗细、缩放和撤销等工具。

不需要画得专业,只要对方看得懂。毕竟是讨论方案,不是现场参加美术联考。

重要结论请及时复制或另行保存,房间协作内容不适合作为长期资料库。

第六步:一起看本地音视频

打开“同播”,可以选择电脑上的音频或视频文件。

Peerloom 音视频同播:选择文件或将本地文件拖入虚线区域

界面截图:音视频同播的文件选择界面。点击“选择文件”,或者直接把文件拖入虚线区域,即可选择要分享的内容。

按顺序操作:

  1. 点击选择文件,或者将本地音频、视频拖入选择区域。
  2. 等待文件加载。
  3. 点击“开始同播”。
  4. 其他成员在房间主区域观看画面或收听音频。
  5. 分享结束后,点击“结束同播”。

这里有几个规则:

  • 同一房间同时只能有一位成员发起同播。
  • 暂停只是暂停播放,仍保留同播控制权。
  • 想换一个人分享,需要先点击“结束同播”。
  • 同播占用媒体席位,席位已满时需要先释放。
  • 发起者正在共享屏幕或摄像头时,需要先结束当前内容。
  • 文件能否播放、浏览器能否捕获媒体,取决于浏览器及媒体编码支持。

“暂停”和“结束同播”是两个不同操作。前者相当于“等一下”,后者才是“下一位”。

10 · 常见问题,先从这里找

遇到连接问题,可以先打开工具栏中的“连接状态”,查看房间连接、服务器请求和媒体状态。

Peerloom 连接状态面板

连接状态实拍:本次截图时只有一位成员,尚未开启媒体,因此媒体路径显示“待检测”、码率为零。这张图展示面板信息,不代表已完成跨设备音视频连通测试。

遇到的问题 优先检查
./peerloom 提示文件不存在 是否在项目目录,编译是否成功
提示 Exec format error 程序是否为当前系统和 CPU 架构编译
启动时提示账号文件读取失败 PEERLOOM_USERS_FILE 路径是否正确、文件是否存在、运行用户是否有读取权限
新增账号后无法登录 是否使用 >> 追加,是否重启了服务,登录时是否输入原始密码
启动提示地址被占用 是否已经有 Peerloom 或其他程序占用了 5050、3478
页面能打开,但无法正常进入房间 检查房间是否存在,以及反向代理的 WebSocket 配置
麦克风或屏幕共享不可用 检查 HTTPS、浏览器权限和操作系统权限
成员能进房,但没有声音或画面 检查外部 IP、TURN 端口、中继 UDP 范围、安全组及端口映射
无法开始同播 检查是否有人正在同播、媒体席位是否已满、本人是否正在共享其他内容
本地文件无法播放 检查浏览器是否支持该文件的媒体编码,先用可正常播放的文件测试
关闭终端后网站不能访问 是否只用了前台启动,是否已经配置后台服务
修改前端后网页没有变化 是否重新构建前端、重新编译并替换程序、重启服务

排查时建议分三步:先确认程序启动,再确认网页和房间连接,最后检查音视频。

不要一上来把所有配置一起改掉,否则原本只有一个问题,很容易被调试成一套问题。

11 · 使用范围与后续更新

Peerloom 使用 WebRTC 传输媒体,并内置 TURN 服务。

网络条件允许时,成员之间可以直接传输;无法直接连接时,可以通过 TURN 中继。因此,实际体验与参与者网络、设备性能和服务器带宽都有关系。

当前媒体使用 WebRTC mesh 方式,人数增加时,客户端连接数量和带宽负担也会增加,更适合小范围讨论、远程演示和团队协作。

还有几点使用边界:

  • 房间聊天不保存历史。
  • 协作文档、白板的重要内容应及时另行保存。
  • 屏幕、麦克风和摄像头需要浏览器及系统授权。
  • 本地音视频同播能力取决于浏览器支持情况。

更新版本前,先备份自己的配置文件和账号文件。获取新版源码后,重新安装需要的依赖、构建前端、编译程序,再替换运行文件并重启服务。

具体参数和后续变动,以项目 README及当前版本源码为准。

Peerloom 基于 Screego 二次开发,感谢原项目及相关开源依赖的贡献者。项目保留 GPL v3 许可证,欢迎体验、提交 Issue,也欢迎参与改进。

在线体验 Peerloom · 查看源码与部署文档

结语:卷起来。毕竟,头发卷起来,显得发量多。

这个假期,休息得够不够不好说,至少以后找人一起看 Bug,不用再隔着聊天框描述“右边那个,再往上一点”了。

Thanks♪(・ω・)ノ 感谢你长得那么好看还来看我的博客!see you around ~

00:00/00:00

顾北辰

?偶遇故人点头微笑^_^心像透明水滴☝没有喜悲…?