frp 内网穿透 + 宝塔 Linux · 双服务器架构
在有公网IP的那台服务器上部署 frps。
下载 frp:
# 下载最新版(以 0.52.3 为例)
cd /usr/local
wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz
tar -zxvf frp_0.52.3_linux_amd64.tar.gz
mv frp_0.52.3_linux_amd64 frp
cd frp
编辑 frps.toml:
# frps.toml bindPort = 7000 # frp 通信端口(frpc 连这个) auth.method = "token" auth.token = "你设置的密钥123456" # frpc 和 frps 必须一致 # 可选:Web 管理面板 webServer.addr = "0.0.0.0" webServer.port = 7500 webServer.user = "admin" webServer.password = "admin123"
启动 frps(systemd 守护):
# 前台测试 ./frps -c frps.toml # 确认可用后,用 systemd 守护(略),或直接后台运行 nohup ./frps -c frps.toml > /dev/null 2>&1 &
在内网那台服务器(装了宝塔/OmeTV 的那台)上配置 frpc。
cd /usr/local wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz tar -zxvf frp_0.52.3_linux_amd64.tar.gz mv frp_0.52.3_linux_amd64 frp cd frp
编辑 frpc.toml(重点:转发 80 和 8282):
# frpc.toml serverAddr = "1.2.3.4" # ← 改成你的 frps 公网IP serverPort = 7000 auth.method = "token" auth.token = "你设置的密钥123456" # 必须和 frps 一致 # 转发网页 (80端口) [[proxies]] name = "web" type = "tcp" localIP = "127.0.0.1" localPort = 80 remotePort = 80 # frps 公网端口 # 转发 WebSocket (8282端口) ★ 关键! [[proxies]] name = "ws" type = "tcp" localIP = "127.0.0.1" localPort = 8282 remotePort = 8282 # frps 公网端口
启动 frpc:
./frpc -c frpc.toml
# 看到 [web] start proxy success 和 [ws] start proxy success 即成功
这是 frp 架构下最容易改错的地方。
前端 WS_URL 必须填 frps 的公网 IP 或域名,不能填内网 IP!
编辑 📄 js/app.js 第 8 行:
WS_URL: 'ws://1.2.3.4:8282', // ← 填 frps 公网 IP // 如果有域名 + HTTPS 则用: // WS_URL: 'wss://你的域名:8282',
| 纠错对比 | ❌ ws://192.168.0.101:8282(内网IP,公网手机连不上) |
|---|---|
| 正确 | ✅ ws://1.2.3.4:8282(frps 公网IP) |
在内网服务器上启动 WebSocket 服务:
cd /www/wwwroot/ome
php server.php start -d
# 或前台调试
php server.php start
确认所有进程都在运行:
# 内网服务器:检查 Nginx(80) 和 Workerman(8282) netstat -tlnp | grep -E ':80|:8282' # 内网服务器:检查 frpc 是否连接成功 ps aux | grep frpc
用手机(4G/5G流量,或任意网络)测试,不要用内网 WiFi:
| ① 网页 | 手机浏览器打开 http://1.2.3.4/(frps公网IP),能看到毛玻璃页面 |
|---|---|
| ② WebSocket | 手机打开 http://1.2.3.4:8282/,显示 "WebSocket workerman" |
| ③ 在线数 | 进入页面,右上角在线数应 ≥ 1(不再是 0) |
| ④ 匹配 | 两个手机同时点匹配,能看到对方视频 |
js/app.js 的 WS_URL 是否改成公网 IP 了。① 检查 serverAddr 是否填了正确的公网 IP
② 检查 auth.token 两端是否一致
③ 检查 frps 的 7000 端口是否在云安全组放行
④ 查看 frpc 日志:./frpc -c frpc.toml 前台看报错
① 检查 frpc.toml 里是否配置了 ws 这条 8282 的转发
② 检查 frps 云安全组是否放行了 8282
③ 手机访问 http://公网IP:8282/ 看是否通
④ 确认内网 Workerman 确实在 8282 监听
① WebRTC 需要 HTTPS(除 localhost 外),纯 HTTP 下摄像头会被浏览器禁止
② 建议给 frps 公网 IP 绑个域名并配置 HTTPS
③ NAT 复杂时需自建 TURN 服务器
WebRTC 的 getUserMedia() 在非 HTTPS 环境下会被浏览器拦截。强烈建议:给 frps 服务器配置域名 + SSL 证书,网页用 https:// 访问,WS 用 wss://。
在域名解析里把域名 A 记录指向 frps 公网 IP,然后把 js/app.js 里改成 ws://你的域名:8282(HTTP)或 wss://你的域名:8282(HTTPS)。
因为 WebRTC 摄像头在 HTTP 下会被浏览器禁止,生产使用必须 HTTPS。推荐做法:
| 域名 | 准备一个域名,A 记录指向 frps 公网 IP |
|---|---|
| 方式A | frps 服务器装 Nginx + 宝塔,配置域名 + Let's Encrypt 证书 |
| 方式B | 内网服务器宝塔配 HTTPS,frp 转发 443 端口 |
配置好 HTTPS 后,前端改成:
WS_URL: 'wss://你的域名:8282', // ← HTTPS 环境用 wss
wss://你的域名/ws/ 走 Nginx 反代,可以复用 443 端口,就不用单独暴露 8282 了。原理和之前局域网教程里 Nginx 反代 /ws/ 相同。