PeerJS+Socket.IO+NodeJS视频通话偶发失效及多房间功能实现求助
你遇到的跨地域/跨网络无法连接的核心原因是WebRTC直连需要NAT穿透,严格NAT网络(如运营商级NAT、企业内网)下必须依赖STUN/TURN中继服务才能正常建立连接,以下是具体解决方案:
一、STUN/TURN服务集成方案
你可以在现有VPS上搭建开源的coturn作为STUN/TURN服务,完全不依赖第三方服务:
- 安装coturn(以Debian/Ubuntu系统为例)
apt update && apt install coturn - 编辑配置文件
/etc/turnserver.conf,修改如下参数:listening-port=3478 tls-listening-port=5349 listening-ip=你的VPS公网IP relay-ip=你的VPS公网IP external-ip=你的VPS公网IP realm=yourdomain.com # 替换为你自己的域名 server-name=yourdomain.com # 复用你现有letsencrypt的SSL证书即可 cert=/etc/letsencrypt/live/yourdomain.com/fullchain.pem pkey=/etc/letsencrypt/live/yourdomain.com/privkey.pem # 自定义TURN服务的账号密码,后续配置前端需要用到 user=自定义用户名:自定义密码 lt-cred-mech no-tlsv1 no-tlsv1_1 - 启动coturn并设置开机自启
systemctl enable --now coturn - 开放VPS防火墙端口:确保3478、5349的TCP/UDP端口,以及现有3030端口对外放行
- 修改前端PeerJS初始化代码,集成STUN/TURN配置:
var peer = new Peer(undefined, { path: '/peerjs', host: '/', port: '3030', config: { 'iceServers': [ { url: 'stun:你的域名:3478' }, { url: 'turn:你的域名:3478', username: '你刚才设置的TURN用户名', credential: '你刚才设置的TURN密码' }, { url: 'turn:你的域名:5349', username: '你刚才设置的TURN用户名', credential: '你刚才设置的TURN密码' } ] } });
注意 配置完成后可以在浏览器控制台查看Peer连接日志,成功获取到turn类型的iceCandidate即说明配置生效。
二、多房间+WordPress对接实现方案
1. 服务端增加房间人数限制
修改服务端socket逻辑,限制每个房间最多2人同时进入:
io.on('connection', socket => { socket.on('the-interview', (data) => { // 获取当前房间已有人数 const roomUsers = io.sockets.adapter.rooms.get(data.room)?.size || 0 // 超过2人直接拒绝加入 if(roomUsers >=2) { socket.emit('room-full') return } socket.join(data.room); // 房间已有1人时才发送新用户连接通知,避免重复触发 if(roomUsers === 1) { socket.to(data.room).broadcast.emit('user-connected', data.id) } }) })
2. WordPress对接逻辑
- 先给Node服务配置Apache反向代理,将
/webrtc/路径代理到127.0.0.1:3030,无需对外暴露3030端口,也方便和WordPress同域名集成 - 在WordPress中添加自定义重写规则,将
/interviews/{房间名}、/visits/{房间名}这类路径的房间名参数提取出来 - 编写WordPress自定义页面模板,将提取到的房间名动态赋值给前端
room变量:<!-- WordPress自定义页面模板中的JS部分 --> <script> // 动态获取PHP传入的房间名 var room = '<?php echo esc_js($提取到的房间名); ?>'; const socket = io('https://你的域名/webrtc') var peer = new Peer(undefined, { path: '/webrtc/peerjs', // 路径对应反向代理前缀 host: '你的域名', port: '443', // 直接用HTTPS默认端口 // STUN/TURN配置和上文保持一致 }) // 增加房间满员提示 socket.on('room-full', () => { alert('当前房间已满,无法加入') }) </script>
内容的提问来源于stack exchange,提问作者mhuenchul
相关产品推荐
相关产品推荐

