feat: 在线双人五子棋(Socket.IO + Vue3 + Canvas)

- 服务端权威状态机:落子校验、四方向五连判胜、悔棋请求、认输、离线判负、交换黑白再来一局
- 断线重连:resumeToken 凭证 + localStorage,刷新/锁屏自动回到原座位
- 移动端 Canvas 棋盘:DPR 适配、触摸容差吸附、最后一手标记、胜利连子高亮
- Docker 多阶段构建,非 root + 只读根文件系统
- k8s 清单:单副本 Recreate(内存态房态)、Ingress WebSocket 超时与粘性会话注释
This commit is contained in:
root
2026-09-10 18:17:10 +08:00
commit 59bfc98afa
22 changed files with 5995 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
# 本机镜像导入集群的两种方式(无镜像仓库场景):
#
# 方式 A:集群就是执行 docker build 的这台机器(单节点或每台节点都构建)
# docker save wuziqi:0.1.0 -o wuziqi-0.1.0.tar
# ctr -n k8s.io images import wuziqi-0.1.0.tar
#
# 方式 B:集群在别的机器上
# docker save wuziqi:0.1.0 -o wuziqi-0.1.0.tar
# scp wuziqi-0.1.0.tar <node>:~/
# 在【每台可能被调度到的节点】上执行:ctr -n k8s.io images import ~/wuziqi-0.1.0.tar
#
# 导入后配合 imagePullPolicy: IfNotPresent 即可直接启动,无需任何 registry。
apiVersion: apps/v1
kind: Deployment
metadata:
name: wuziqi
namespace: wuziqi
labels:
app: wuziqi
spec:
# 【必须保持为 1】
# 房间与棋局状态存放在进程内存(RoomManager),多副本会各自持有一份状态:
# 两名玩家被 Ingress 分流到不同 Pod 时,第二个玩家会看到"房间不存在"。
# 若确实需要多副本,必须引入 Redis + Socket.IO Redis Adapter,并把房间状态外置。
replicas: 1
strategy:
# Recreate:先终止旧 Pod 再创建新 Pod。
# 默认的 RollingUpdate 会让新旧两个 Pod 短暂并存,此时新 Pod 内存里没有旧 Pod 的房间,
# 进行中的对局会"房间丢失"。
type: Recreate
selector:
matchLabels:
app: wuziqi
template:
metadata:
labels:
app: wuziqi
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
# 内存态服务,收到 SIGTERM 后推完最后一次状态即可退出
terminationGracePeriodSeconds: 15
containers:
- name: wuziqi
image: wuziqi:0.1.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 3000
env:
- name: PORT
value: "3000"
- name: NODE_ENV
value: production
readinessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 2
periodSeconds: 10
timeoutSeconds: 3
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 5
periodSeconds: 20
timeoutSeconds: 3
failureThreshold: 3
resources:
requests:
cpu: 20m
memory: 64Mi
limits:
cpu: 500m
memory: 256Mi
securityContext:
allowPrivilegeEscalation: false
# 进程不需要写文件系统,静态资源与构建产物都是只读的
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL