搭建你自己的“云游戏”

1小时搭建游戏远程串流,你专属的“云游戏”

本文将会介绍如何利用云服务器打造自己的云游戏服务。你需要:

  • 一台云服务器(本文会介绍配置要点)

  • 一台实际运行游戏的PC,必须使用Nvidia显卡(A卡还真不行,至于Intel显卡用户……等等,你应该不会用Intel核显玩游戏吧?)

  • 熟悉基本Linux系统操作

为什么要自建远程串流?

如果你有一台性能强劲的台式机,或者性能强劲的游戏本(但是很重不想带出门),那么在外玩游戏串流游玩就是不错的选择。在国外,有微软的xCloud、Google的Stadia、英伟达的Geforce Now等众多云游戏平台,但国内的选择寥寥无几,能游玩的游戏也是少得可怜。因此,自建游戏串流就成了一个有吸引力的选择。本文将教会你如何使用frp和Moonlight实现远程串流。如果你只想局域网串流,请直接翻到“配置Moonlight串流”部分。

延迟如何?

40ms。这是我自己配置的结果(5G网络下)。这已经和主流电视的响应速度差不多了。虽然和显示器的10ms仍有差距,但已经在可接受的范围内了。

如何选择云服务器?

对我们的需求而言,服务器的性能、内存大小、磁盘速度和容量等都无关紧要。我们需要关注的有两个:地理位置和网络带宽。其中地理位置决定延迟,带宽决定串流画质。

地理位置推荐选择尽可能离自己近的区域。例如,我在杭州,就首选杭州的云服务器。如果云服务厂商没有杭州数据中心,那就选物理位置上海的云服务器。离你越近,延迟就越低。这主要倒不是因为光信号传输需要时间,而是距离越远,网络信号就会经历越多的交换机,导致延迟增高。

网络带宽能有多高就选多高,最高不超过运行游戏的主机的上传带宽。不过,你会发现云服务器的网络带宽费用高得离谱,1Mbps一年就要100元以上。就算按量计费,以华为云收费标准为例,1GB要收0.8元,如果以50Mbps码率完一小时游戏,就要花掉17块钱,仍然算不上便宜。所以,这时候如果你正好有学校送的大额抵扣券,就很划算了。你可以根据自己需求选择合适带宽:

  • 720P 30fps 至少5Mbps带宽(能玩就成)

  • 720P 60fps 至少8Mbps带宽(糊是糊了点,但好歹还挺流畅的)

  • 1080P 30fps 至少8Mbps带宽(清晰倒还挺清晰的,就是这主机级帧率有些难受)

  • 1080P 60fps 至少15Mbps带宽(挺舒服的,在手机平板上玩已经很清晰了,而且也很流畅)

  • 4K 60fps 至少50Mbps带宽(土豪专用)

服务器操作系统推荐选择Ubuntu 20.04 LTS。另外,我没测试过非x86架构的服务器,但是仅就我们的需求而言,应该是没问题的。如果你没有大额抵扣券,可以关注一下腾讯云的优惠活动,它还是挺良心的(我现在就在用一台仅74元一年的4核CPU4GB内存8Mbps带宽的主机)。

配置frp内网穿透

配置frp内网穿透

由于国内IPv4地址短缺,因此你用的基本上都是共享IP。虽然理论上IPv6可以解决这一问题,但我实际测试还是不行。所以,我们需要使用内网穿透转发网络请求。接下来介绍开源免费的最流行的内网穿透软件frp的用法。

下载可执行文件

首先,去frp的GitHub repo的releases里找到最新版本的可执行文件。例如,我使用x86 64位的Ubuntu 20.04系统,就选择frp_0.42.0_linux_amd64.tar.gz。通常使用linux_amd64的版本。然后右键复制链接,用wget下载下来即可。

wget https://github.com/fatedier/frp/releases/download/v0.42.0/frp_0.42.0_linux_amd64.tar.gz

但是这里有个问题:由于伟大防火长城的存在,有时服务器并无法连接上GitHub。那怎么办呢?我在我自己的服务器上放了一个frp_0.42.0_linux_amd64.tar.gz,实在不行可以从我的服务器获取:

wget https://toys.gzblog.tech/frp_0.42.0_linux_amd64.tar.gz

下载好了之后,解压:

tar -xzvf frp_0.42.0_linux_amd64.tar.gz

删除压缩包,将文件夹改名为frp,进入文件夹:

rm frp_0.42.0_linux_amd64.tar.gz ; mv frp_0.42.0_linux_amd64 frp && cd frp

里面有若干文件,其中可执行文件frps用于服务端,frpc用于客户端。

配置frp

frps的配置文件为frps.ini,将其内容改为如下:

[common]
bind_port = <any port range [7000, 65535]>
bind_addr = 0.0.0.0
token=<your password here>
allow_ports = 47000-49000, 3389
tls_enable=true

注意将token更改为你自己的密码,bind_port为任意端口。记住这两个的值,后面会用到。

allow_ports中各个端口含义如下:

  • 47000-49000:这个端口段包含了Moonlight需要的所有端口。

  • 3389:Windows 远程桌面用到的端口。这个东西值得单独写一篇文章,这里暂且不提。

我们启用了tls传输加密,这有助于让frp在学校或者实验室Wi-Fi等防火墙比较严格的网络下仍然保持工作。

开机自启

现在,你就可以启动frp了:

nohup ./frps -c frps.ini

但是这么做有个问题:每次服务器开机,你都必须ssh到服务器上来这么一下。太麻烦了。所以我们配置一下frp开机自启。我们使用systemd来实现开机自启,这需要写一个配置文件:

vim /usr/lib/systemd/system/frps.service

输入:

[Unit]
Description=Frp Server Service
After=network.target

[Service]
Type=simple
User=john
Restart=on-failure
RestartSec=5s
ExecStart=/home/john/frp/frps -c /home/john/frp/frps.ini

[Install]
WantedBy=multi-user.target

其中ExecStart后的路径请改成你自己的路径。user也改成你自己的Linux用户名。

然后,启动 frps:

sudo systemctl start frps

查看frps的状态:

systemctl status frps

若是active(running),就说明我们配置成功啦!然后启用开机自启:

sudo systemctl enable frps

至此,服务端的配置都已完成!

配置frp客户端

首先,去frp的GitHub repo的releases下载对应你本地游戏主机的版本。你可能已经发现了:这个压缩包里同时包含了服务端和客户端。我只有Windows设备,所以其它系统的用户请自行解决——流程基本上是一模一样的。客户端的配置文件为frpc.ini,修改其内容如下:

[common]
server_addr = <Your server IP>
server_port = <Your selected port>
token = <Your password>

[nvidia-stream-tcp-1]
type = tcp
local_ip = 127.0.0.1
local_port = 47984
remote_port = 47984

[nvidia-stream-tcp-2]
type = tcp
local_ip = 127.0.0.1
local_port = 47989
remote_port = 47989

[nvidia-stream-tcp-3]
type = tcp
local_ip = 127.0.0.1
local_port = 48010
remote_port = 48010

[nvidia-stream-udp-1]
type = udp
local_ip = 127.0.0.1
local_port = 5353
remote_port = 5353

[nvidia-stream-udp-2]
type = udp
local_ip = 127.0.0.1
local_port = 47998
remote_port = 47998

[nvidia-stream-udp-3]
type = udp
local_ip = 127.0.0.1
local_port = 47999
remote_port = 47999

[nvidia-stream-udp-4]
type = udp
local_ip = 127.0.0.1
local_port = 48000
remote_port = 48000

[nvidia-stream-udp-5]
type = udp
local_ip = 127.0.0.1
local_port = 48002
remote_port = 48002

[nvidia-stream-udp-6]
type = udp
local_ip = 127.0.0.1
local_port = 48010
remote_port = 48010

注意将server_addrserver_porttoken这三项设置为你自己的。尽管有Windows版本,但frpc.exe是一个只能从命令行执行的程序,是不能双击运行的。右键frpc所在文件夹的空白处,选择在此处打开 Powershell,输入:

./frpc -c frpc.ini

若没有报错,说明运行成功。如果报端口被占用的警告,请检查有没有第二个frpc在运行。接下来,我们要让frpc开机启动。

frp客户端开机自启

这里本来应该使用Windows计划任务实现开机自启的,但计划任务在Windows 11 22581版本里被微软搞坏了,所以我不得不使用一种替代方案。

frpc所在目录下新建一个名为start.bat 的批处理文件,内容如下:

@echo off
:home
frpc -c frpc.ini
goto home

双击这个文件,就会蹦出来一个窗口启动frpc。

然后再新建一个名为startfrp.vbs的VB Script脚本,它是用来隐藏那个蹦出来的窗口的。其内容如下:

CreateObject("Wscript.Shell").run "cmd /c start.bat",vbhide

然后,给VBS脚本创建一个快捷方式,放到Windows开机启动文件夹里,这个文件夹可以这么打开:

按 win + R 打开运行窗口
输入 shell:startup ,然后回车

这样,frpc就能在Windows上开机自启啦!

配置Moonlight串流

Moonlight 是什么?

Nvidia曾经推出过一个电视盒,叫Nvidia Shield。为了让Nvidia显卡用户能通过Shield在电视上玩游戏,Nvidia为它开发了一种专门的串流协议。这种协议使用Nvidia显卡的硬件编解码单元,几乎不会给显卡带来额外负载,而且画质非常好、延迟也很低。Moonlight是一个开源免费的游戏串流客户端,它能把运行它的设备模拟成Shield,这样我们就可以享受Shield一般的高质量远程游戏体验啦。

如何配置Moonlight?

网络

为了得到最低的延迟以及提升稳定性,推荐让游戏电脑使用有线网。如果使用局域网串流,注意Wi-Fi要连接到5G频段,最好使用Wi-Fi 6。

电脑

你需要安装Nvidia Geforce Experience,在它的设置中找到并启用Shield串流服务。这个客户端以难以登录著称,无论你是否使用科学上网,无论你使用它提供的哪种登录方式。但是不登录Nvidia账号,它又不让你用任何功能,哪怕更新驱动都不行。所以,你可能得和它较劲一会儿了。什么Geforce Experience,明明是Bad Experience。

此外,由于Shield串流协议的限制,在串流时电脑屏幕必须开着,或者你也可以用某宝9.9的HDMI欺骗器。

客户端

Moolight 有各种平台的客户端,无论你使用Windows、macOS、Android还是iOS。不过,iOS版的Moonlight延迟要比安卓版低一些。确保客户端和游戏电脑在同一个网络下,你应该能看到一个带挂锁的电脑图标,点击它,在电脑上输入它显示的配对码,就配对成功了。这个时候,你就已经能在局域网里享受游戏串流了。根据我的亲身体验,Moonlight局域网串流的延迟几乎可以忽略不计,唯一的缺憾是它不能转发UWP应用专用的Xbox手柄扳机震动。

让Moonlight使用公网串流

从Moonlight的来历你可以看出,它本来只是用来局域网串流的。不过,通过之前配置的内网穿透,你做到了把内网端口暴露到公网,这样就达到了远程串流的目的。在Moonlight客户端中“Select New Host”界面中点击“Manually Add Host”,输入服务器的IP地址,它会提示已经更新Host信息。现在,你就可以通过公网进行远程串流啦!并且,在局域网里,Moonlight会自动切换为局域网串流,获得更低的延迟、更高的画质。

也是一个很好的远程桌面……

Moonlight串流的画面质量很高,当作远程桌面来用完全没问题。不过,它默认只让你启动游戏,那怎么办呢?你可以启动一个不会立即进去的游戏,比如CS:GO,然后把它晾着去干别的事情。其实,还有一种更优雅的解法:在Geforce Experience里把C:\Windows\System32\mstsc.exe添加到游戏列表里,在Moonlight里点mstsc就能直接进桌面了。其实mstsc.exe是Windows 远程桌面的exe,Moonlight并没有真的去执行它,Moonlight实际上相当于收到了一个信号,那就是你想直接进桌面。至于为什么设计得这么奇怪,那你得问Nvidia。

用Moonlight做远程桌面还有一些额外好处:

  • 系统动画都得到保留,并且动画都很流畅

  • 可以正常使用用到GPU的软件

但相比RDP,它的缺点也很明显:

  • Moonlight一直以设定的最高码率传输数据,流量消耗明显高于RDP

  • 无法自适应更改屏幕分辨率

  • 无法在远程电脑和本地电脑之间共享剪贴板、传输文件

  • 与RDP不兼容,RDP连过一次之后Moonlight就用不了了

  • 不支持Remote App

  • 不支持多显示屏

  • 只能在Nvidia显卡的电脑上使用

这倒不是说Moonlight作为一个远程桌面不好,实际上它要比市面上绝大部分远程桌面软件——比如TeamViewer、向日葵——都要优秀很多,只是RDP实在是太太太太太优秀了。至于RDP的妙处都在哪里,该如何使用,我以后再聊 :)

评论

此博客中的热门博文

标点论

SSH可以做任何事情!