基于 Zerotier + Sunshine + Moonlight 实现赛博约会

基于 Zerotier + Sunshine + Moonlight 实现赛博约会

和朋友们远程同乐的解决方案~

Intro

我有一个一直以来蛰伏在心里的想法或者说需求,能不能低延迟地与朋友们公用同一台主机,实现即使相隔千里,也能和他们共同观赏一部电影,或者说一起玩一些只支持本地联机的游戏。你可能会说,steam 推出过远程同乐的功能,但是由于高墙的原因,这项服务在国内的稳定性不尽如人意;而类似“一起看电影”的服务,现在也是少之又少,难道我要自己架设一个 HTPC 服务器吗?可这个方案付出的成本对于我这种节省主义者来说过于不可忽视了。直到我在网络工程专业进修了三年,我终于了解到了解决办法:

技术梗概

Zerotier

ZeroTier 使用 SDN(软件定义网络)原理,在IP层面上建立虚拟网络。每个参与的设备都有一个全局唯一的标识——ZeroTier ID,这使得无论物理位置如何,都能像在同一局域网内一样通信。

原理

Zerotier 在多设备之间通过 NAT 打洞的方式来建立 P2P 连接,如:在笔记本电脑、台式机、嵌入式设备、云资源和应用。这些设备只需要通过 ZeroTier One ( ZeroTier 的客户端) 在不同设备之间建立直接连接,即使它们位于 NAT 之后。关于 NAT 打洞可以查看本博客的另一篇文章:NAT 打洞技术

zt.png

关键词

以下是我们用户在使用 Zerotier 过程中需要关注的几个关键词:

  • Planet:行星服务器,Zerotier 根服务器。官方文档如此描述:There is only one planet. Earth's root servers are operated by ZeroTier, Inc. as a free service. 意思是这是由 Zerotier 官方运营的一项免费服务,也就是说这个世界上只有一个 Planet。
  • Moon:卫星服务器,用户自建的私有根服务器,起到代理加速的作用。因为大家都懂的原因,Planet 提供的服务不尽稳定,所以我们可以建立自己的 Moon 节点来提供代理服务。
  • Leaf:网络客户端,每台连接到网络节点,也就是我们使用的电脑、平板、手机等。

Moonlight

Moonlight(前身为 Limelight)是 NVIDIA GameStream 协议的开源实现,它实现了 NVIDIA Shield 使用的协议,并编写了一组第三方客户端。

在Moonlight - Sunshine 体系下,它是客户端,接收经过编码的信息并解码。

Sunshine

Sunshine 是为 Moonlight 提供游戏串流服务的,可以自己部署的主机服务端 。它提供低延迟的云游戏服务器功能,支持 AMD、Intel 和 Nvidia GPU 的硬件编码(软件编码也可用)。Moonlight 客户端可以连接到部署了 Sunshine 的设备。

也就是说,在 Moonlight - Sunshine 这对兄弟中,Sunshine 是一种作为服务端的存在,它将经过编码的信息推送出去。

搭建

Zerotier

服务端

刚才说过,我们的在服务端的工作就是自建一个 Moon 节点,来代理官方的 Planet 节点。同时,我们还需要一个带有 UI 的控制界面 ztncui。因为最终的连接是 P2P 的,很少需要由 Moon 主动转发数据,所以服务器的要求很低。

前期准备
  • 配置服务器的防火墙策略,开放 3443/tcp 端口,4000/tcp 端口用于 ztncui 的访问,9993/tcp 端口,9993/udp 端口。
  • 服务器安装了 docker,git。
docker 安装 ztucui
docker run --restart=on-failure:3 -d --name ztncui -e \
HTTP_PORT=4000 -e HTTP_ALL_INTERFACES=yes \
-e ZTNCUI_PASSWD=admin@123 \
-p 4000:4000 keynetworks/ztncui

web 的管理页面是 4000 端口(也就是我们放通的端口),我们可以去看看有没有成功安装:通过浏览器访问 ip:4000 进入管理页面。

启动起来后,使用默认的账号 admin 登录进去,密码是 admin@123,登陆后会被要求重置密码。

搭建 Moon 服务器

截至上一步,已经可以创建网络了,但是那使用的还是 Zerotier 的官方服务,我们需要搭建自己的 Moon 服务。

# 创建一个持久化存放文件的目录
mkdir -p /opt/docker/moon
# 获得云服务器的公网ip
public_ip=`curl ip.sb`
# 建立moon服务器
docker run --name zerotier-moon -d -p 9993:9993 -p 9993:9993/udp -v /opt/docker/moon:/var/lib/zerotier-one jonnyan404/zerotier-moon -4 $public_ip

到此我们的服务端就搭建好了。查看一下日志,记录一下 moon id,后面加入会用到。

docker logs -f zerotier-moon
创建一个网络

create network

创建完成后会得到一串神秘代码,记录下它。

get token

回到上一级,通过 easy set up 进行设置。

屏幕截图 2024-04-11 122307.png

设置好以后,服务端的配置就告一段落了。

客户端

下载

进入 Zerotier 官网 选择对应系统的版本下载,这里我下载的是 Windows。

完成安装后,加入网络,输入我们在 ztncui 网页上创建的网络的那个神秘代码:

join

授权

回到 ztncui,对它进行授权(可能需要等一会儿才会显示出来)

authorized

加入 Moon

最后在配置一下加入 moon 服务器,打开 cmd。

cd C:\ProgramData\ZeroTier\One
zerotier-cli orbit [moon_id] [moon_id]

将之前记录的 moon id 填进去后执行。

join moon

看看有没有成功加入 Moon。

zerotier-cli listpeers

check

至此已成功加入本机至虚拟网络中,我们可以用同样的步骤让我们的朋友或是自己其他的设备添加进来,记得进行授权喔。

客户端 - 安卓

准备

想要把安卓设备添加到自建的 Moon 节点中需要用到一个第三方的应用,是由一位大神编写的,我们下载并安装到设备。

项目地址:https://github.com/kaaass/ZerotierFix

还需要从我们自己的服务器下载两个文件,如果你是腾讯云,可以使用 OrcaTerm 中文件传输的功能,当然也可以使用 Xftp 等:

*.moon 路径参考图片:

moon-tuya.png

planet 路径参考图片:

planet-tuya.png

下载后把这两个文件也传输给安卓设备,传输完成后具体操作如下:

  • 打开安卓设备上安装好的 ZerotierFix
  • 右上角设置
  • 启动自定义 planet
  • 选择从文件导入
  • 选择刚才的 palnet 文件,提示导入成功,切换 planet 成功
  • 再右上角
  • 入轨
  • 右下角加号
  • 从文件导入
  • 选择刚才的 moon 文件
  • 提示成功,会在入轨界面看到 moon 服务的 id。
  • 回到上一级,右下角加号
  • 输入网络 ID 加入网络
  • 在 ztncui 上授权
  • 完成加入

success.jpg

至此,Zerotier 组网已经完全完成。

Sunshine

项目地址:https://github.com/LizardByte/Sunshine/releases

直接下载安装就行,打开后显示 Web UI,就可以啦!很简单吧。

sunshine

Moonlight

安卓版本下载地址 https://github.com/moonlight-stream/moonlight-android,有需要也可以下载其他平台版本。

  • 安装后,由于此时我们已经在同一个虚拟局域网内,Moonlight 会自动搜索到主机。
  • 点击主机,不出意外,在要链接的电脑上会弹出和 Sunshine 配对的 PIN 码,输入 Moonlight 提供的 PIN 码,配对成功。
  • 点击 DESKTOP,成功开始串流

stream success

Moonlight 还有很多有意思的功能,也有很高的自定义自由度,比如我可以在平板上使用手写笔,或者新建一个虚拟屏幕。让串流画面输出虚拟屏幕内容,以此来把平板当作一块副屏。这些内容都可以进一步探索。

总结

至此,我们完成了串流环境的部署,在平板使用手机热点、笔记本使用校园网的情况下,采用 1080P@60 fps 的画面,延迟可以稳定在 50 ms 以内,这个数字足以支撑我和朋友们联机游玩一些本地联机的游戏,或者一起看看番剧电影了。话不多说,赶快和你的朋友们一起愉快的玩耍吧!

参考:
https://blog.csdn.net/gitblog_00029/article/details/137257235
https://www.bilibili.com/video/BV1Vh411F7Mr/
https://zhuanlan.zhihu.com/p/522761845

LICENSED UNDER CC BY-NC-SA 4.0
Comment