编辑
2026-06-29
折腾
00

目录

5001端口只能跑一个游戏?那我写个游戏大厅不就行了
第一步:复制粘贴(不是)
第二步:写大厅
第三步:杀死一个不死的进程
第四步:作案凶手
第五步:收工
总结

5001端口只能跑一个游戏?那我写个游戏大厅不就行了

事情是这样的。

我之前让我的 AI 助手(一只叫 Nya酱的傲娇猫娘女仆,对就是那种嘴上说"我才不是想帮你"但什么都帮你做好的那种)帮我写了两个网页小游戏——一个是赛博朋克风的霓虹21点,另一个是 Vue3 写的赛博老虎机

霓虹21点一直跑在 5001 端口上,用 systemd 挂着,稳如老狗。老虎机写完之后就一直躺在网盘里吃灰。

某天我突然想到:老虎机也部署上去吧。但 5001 已经被霓虹21点占了。

两个选择摆在面前:

  • 方案 A:给老虎机单独开个 5002 端口。简单粗暴,但以后每加一个游戏就得开一个新端口,活像开连锁店。
  • 方案 B:写一个游戏大厅,5001 作为入口,所有游戏从大厅点进去加载。

我选了 B。毕竟懒人讲究一个「一次折腾,终身省事」。


第一步:复制粘贴(不是)

老虎机的代码在网盘的 游戏/老虎机游戏/dist/ 下面,是一个 Vite 打包好的纯静态项目。直接把整个 dist 目录复制到 /var/www/games/slot-machine/

霓虹21点本来就在 /var/www/games/neon-blackjack/ 下面,不用动。

目录结构就变成了:

/var/www/games/ ├── neon-blackjack/ ← 霓虹21点 └── slot-machine/ ← 老虎机

行,文件到位了。接下来要写大厅页面。


第二步:写大厅

大厅的思路很简单:

  • 一个首页,列出所有游戏,每张卡片带图标、名称、一句话介绍
  • 点击卡片 → 游戏在一个全屏 iframe 里加载
  • 顶部有个「返回大厅」按钮,也能按 Esc 返回

用纯 HTML+CSS+JS 一把梭,不引任何框架。暗色背景 + 霓虹渐变,跟 21 点的赛博风格保持一致。

游戏卡片的设计偷了个懒:直接用 emoji 做图标。🃏 是21点,🎰 是老虎机。两个卡片的 hover 光晕颜色不同——21点是青色,老虎机是粉色——不仔细看根本注意不到,但加了就是比不加舒服。

手机端也顺手做了适配。用的还是那套老规矩:所有移动端样式全部锁在 @media (max-width: 700px) 里面,桌面端逻辑完全不动;禁止下拉刷新、禁止长按出菜单。

写完一看——嗯,能用。


第三步:杀死一个不死的进程

接下来就是部署环节。先停掉旧的 5001 服务:

bash
kill 3942017

然后启动新的,让 http.server 指向 /var/www/games/(而不是之前的 neon-blackjack/)。

bash
python3 -m http.server 5001 --directory /var/www/games &

curl 一把看看:

<title>霓虹21点 V2 — Neon Blackjack</title>

???

不是,我明明指向了 games 目录,为什么返回的还是霓虹21点?

查文件——对,/var/www/games/index.html 确实是我刚写的大厅页面,标题是「🎮 游戏专区 — Game Hub」。但 curl 拿到的就是霓虹21点。

ps aux 一看:

python3 -m http.server 5001 --directory /var/www/games/neon-blackjack

???我明明启动的是 games,为什么又变成了 neon-blackjack??

杀了,重启,curl——还是霓虹21点。再杀,再启,再 curl——还是。

这一刻我真的有点怀疑人生。


第四步:作案凶手

排查了 crontab、systemd timers、pm2、supervisor……全没有。

最后在 systemd 里找到了:

bash
systemctl list-units --type=service | grep -i "blackjack"

输出:

neon-blackjack.service loaded active running

我盯着这行字看了五秒,然后慢慢打开了它的配置:

ini
[Service] ExecStart=/usr/bin/python3 -m http.server 5001 --directory /var/www/games/neon-blackjack Restart=always RestartSec=3

Restart=always。RestartSec=3。

翻译成人话就是:不管你杀多少次,3 秒后老子原地复活,并且复活之后还是用原来的参数(--directory neon-blackjack),不是你嘴上说的 --directory games

我杀了几次都没发现这事,因为它每次都在 3 秒内重生了,快到我以为是同一个进程还在跑。

改 service 文件,把 --directory 指向 /var/www/games,重载,启动。再 curl:

<title>🎮 游戏专区 — Game Hub</title>

终于对了。


第五步:收工

打开浏览器访问 http://tiaotiaohu0516.cn:5001/

  • 🃏 霓虹21点 —— 点进去,加载正常,荷官照常发牌
  • 🎰 赛博老虎机 —— 点进去,Vue3 正常跑,模式选择画面出来了
  • 两个游戏来回切换,iframe 加载、Esc 返回,全程丝滑,控制台零报错

从「5001 端口不够用」到「游戏专区上线」,总共也就花了一两个小时,其中一半时间在跟 systemd 的 Restart=always 斗智斗勇。


总结

  1. systemd 的 Restart=always 是个好东西,但前提是你记得它存在。 不然就会像我一样反复杀一个杀不死的进程,还百思不得其解。
  2. 游戏大厅用 iframe 加载子游戏,好处是完全解耦。 每个游戏的代码独立维护,互不影响。以后加新游戏只需要两步:复制到子目录,在大厅 HTML 里加一张卡片。
  3. 端口不是问题,架构才是。 5001 只是一个入口,里面可以装无数个游戏——这就是「游戏专区」而不是「游戏端口」的思路。

最后,这篇博客的标题本来想叫《5001端口的奇幻冒险》,但太中二了,放弃了。

以后还想加什么游戏再说吧。反正框架已经搭好了,加新游戏跟往书架上插本书一样简单。

本文作者:haotian

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!