元宇宙中的虚拟办公室SkyOffice

最近因为 Facebook 改名为 Meta元宇宙 一下刷了屏,虽然还没有一个被广泛认可的确切定义,但是不耽误牛叉的人已经通过这个概念赚到了钱💰

今天折腾的 SkyOffice 在老苏看来应该是 元宇宙 的一个场景,在一个沉浸式的虚拟办公室,通过 WebRTC 进行视频交流,这是老苏认为当下比较靠谱的一个应用场景,其他的还包括线上音乐会,线上时装秀等等

什么是 SkyOffice ?

SkyOffice 是使用 PhaserReactReduxPeerJSColyseus 构建的沉浸式虚拟办公室。用户通过虚拟形象出现在网络中,可以进行网络会议。

  • Phaser3 - 游戏引擎
  • React/Redux - 前端框架
  • PeerJS - 用于视频/屏幕共享的 WebRTC
  • Colyseus - 基于 WebSocket 的服务器框架
  • TypeScriptES6 - 适用于客户端和服务器端

官方的体验地址:https://skyoffice.netlify.app

构建镜像

如果你不想自己构建,可以跳过,直接阅读下一章节

老苏把前、后端整合在一个镜像中,容量有点大,大概有 1.2G,就当是虚拟机吧

虽然没有采用分层构建,但是前端是用的编译好的静态文件。因为从 Docker 直接构建的存在有问题,所以只能先编译好 build 目录,再将 build 拷贝到镜像中,这也是没办法的办法吧,如果可能的话建议直接用源代码运行会比较好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
FROM node:16.5
LABEL maintainer=laosu<wbsu2003@gmail.com>

ENV BACKEND_URL="wss://sky-office.herokuapp.com"

WORKDIR /app
COPY . .

# 前端
WORKDIR /app/client
RUN npm install -g serve --registry=https://registry.npm.taobao.org

# 后端
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org

# 安装 Supervisor 和其他依赖
RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list \
&& apt-get clean \
&& apt-get update \
&& apt-get -y install supervisor

# supervisor 配置
COPY supervisord.conf /etc/supervisord.conf

# 脚本文件
COPY replace_api_url.sh ./client/replace_api_url.sh
RUN chmod +x /app/client/replace_api_url.sh

EXPOSE 2567 3000

ENTRYPOINT ["supervisord","-c","/etc/supervisord.conf"]

supervisord.conf 文件是新增用来控制进程的,backend 是服务端,frontend 是前端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[include]  
files = /etc/supervisor/conf.d/*.conf

[program:backend]
priority=1
directory=/app
command=npm run start
autostart=true
autorestart=true
startretries=3
startsecs=1
user=root

[program:frontend]
priority=3
directory=/app/client
#command=serve -s build -n -l 3000
command=/app/client/replace_api_url.sh
autostart=true
autorestart=true
startretries=3
startsecs=1
user=root

[supervisord]
nodaemon=true
logfile=/tmp/supervisord.log
pidfile=/tmp/supervisord.pid
loglevel=debug
logfile_maxbytes=10MB

[supervisorctl]

replace_api_url.sh 文件用于替换 ENV 设置的 BACKEND_URL

1
2
3
4
5
#!/usr/bin/env sh  

find '/app/client/build/static/js' -name '*.js' -exec sed -i -e 's,'wss://sky-office.herokuapp.com','"$BACKEND_URL"',g' {} \;

serve -s build -n -l 3000

构建镜像和容器运行的基本命令如下👇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 下载源代码
git clone https://github.com/kevinshen56714/SkyOffice.git

# 如果 github 慢或者访问不了
git clone https://hub.fastgit.org/kevinshen56714/SkyOffice.git

# 进入目录
cd SkyOffice/client

# 将前端编译生成静态文件
npm install && npm run build

# 记得删除 SkyOffice/client/node_modules 目录,不然镜像会更大

# 回到 SkyOffice 目录
cd ..

# 将 Dockerfile、supervisord.conf、 replace_api_url.sh 放在 SkyOffice 目录下

# 构建镜像
docker build -t wbsu2003/skyoffice:v1 .

# 生成容器(局域网)
docker run -d \
--name=skyoffice \
-p 2567:2567 \
-p 2568:3000 \
-e BACKEND_URL=ws://192.168.0.114:2567 \
wbsu2003/skyoffice:v1

# 生成容器(互联网)
docker run -d \
--name=skyoffice \
-p 2567:2567 \
-p 2568:3000 \
-e BACKEND_URL=wss://map.laosu.ml \
wbsu2003/skyoffice:v1

准备

准备好两个域名,一个给 前端 ,一个给 后端,选好两个不冲突的端口,不确定的话可以用命令查一下

1
2
# 查看端口占用
netstat -tunlp | grep 端口号

老苏没有公网 IP,采用 frp 做的内网穿透,并做了泛域名解析,不了解的可以翻翻老苏以前的文章

容器端口 域名
后端 2567 map.laosu.ml
前端 2568 skyoffice.laosu.ml

后端

群晖的 IP192.168.0.197

进入 自定义标题,新增 WebSocket

这一步很重要,不然首页会卡在 loading

前端

前端必须使用 https 协议,否则在浏览器上无法使用音视频设备

安装

在群晖上以 Docker 方式安装。

在注册表中搜索 skyoffice ,选择第一个 wbsu2003/skyoffice,版本选择 latest

端口

本地端口 容器端口
2567 2567
2568 3000

环境

可变
BACKEND_URL 默认值为 wss://sky-office.herokuapp.com

如果你不改,你的容器将连接到官方服务器,但在国内 heroku 需要科学上网,否则你可能会一直卡在首页 loading,这个问题困扰了老苏一个礼拜,直到后来在 /SkyOffice/client/src/services/Network.ts 中发现红框中的代码 ,才知道 production 模式下并不是连的自己的服务器

BACKEND_URL 只能使用 ws协议或者 wss 协议,不能用 http 或者 https 协议,这是需要特别注意的。

根据我们在准备环节的设置,这里的 BACKEND_URL 应该为 wss://map.laosu.ml

如果你的域名带端口,这里也要带上

运行

稍等一会儿,在浏览器中输入 http://群晖IP:2568 或者 https://skyoffice.laosu.ml 就能看到主界面

如果一直在显示 loading请仔细检测前面的设置是否正确,如果地图已经出来,可以设置好 Name 后点 JOIN 进入

【注意事项】:
如果在同一台机器上开两个页面,或者两台测试机靠的比较近,建议关闭声音,否则比较容易产生啸叫

启用摄像头

要想打开摄像头,需要启用 https 协议,这一点老苏在之前多次提到,可以直接用反代实现的 http 协议转 https 协议

  • 如果你是通过 http://群晖IP:2568 访问的,点 CONNECT WEBCAM 是没有反应的

  • 如果你是用 https://域名 ,就像老苏用 https://skyoffice.laosu.ml 打开的网址,点 CONNECT WEBCAM,授权之后右上角会出现你的视频

屏幕共享

JOIN 之后,你可以通过方向键在地图上随意行走,当你来到电脑前面时,会显示 Press R to use computer,意思是按 R 键使用电脑

R 键之后会显示 屏幕共享

点左上角的 SHARE SCREEN 开启屏幕共享,可以选择要共享的内容

视频会议

当在会议室时,会提示 Press E to sit,意思是按 E 键可以坐下

坐下之后,老苏又登了一个账号 xiaosu

只要进入会议室就开始显示对方的视频窗口

视频聊天

这是基于距离的交互系统,只要两个人的距离接近,就会启动视频窗口

小结

这应该还是个原型应用,理论上你可以构建自己的办公室环境,想象一下,平时在不同区域分、子公司上班的人在 SkyOffice 中通过 WebRTC 随时可以视频交流,是不是有种天涯若比邻的感觉?

参考文档

kevinshen56714/SkyOffice: Immersive virtual office built with Phaser, React, Redux, PeerJS, and Colyseus.
地址:https://github.com/kevinshen56714/SkyOffice