Express搭配Socket.IO服务端无法向指定接收方推送事件导致视频通话异常
问题根源
1. Socket.IO 跨域配置错误
服务端初始化Socket.IO时,CORS配置的请求方法键名写错,将methods写成了单数method,导致跨域配置不生效,浏览器会拦截服务端推送的callAccepted事件。
2. 事件监听位置不合理
你将callAccepted事件的监听逻辑写在了callUser函数内部,只有触发呼叫操作后才会注册监听,虽然当前场景可覆盖,但存在监听未注册导致收不到事件的风险,更稳妥的做法是全局注册监听。
修复步骤
第一步:修复服务端CORS配置
将服务端Socket.IO初始化代码修改为:
const io = require('socket.io')(httpServer, { cors: { origin: ['http://localhost:3000', 'http://localhost:3001'], methods: ['GET', 'POST'], // 修改为复数methods credentials: true } });
可选优化:补全服务端启动日志,方便调试:
httpServer.listen(4000, () => console.log('Listening on port 4000...'));
第二步:调整前端事件监听位置
两个前端实例都做相同修改:将callAccepted事件监听从callUser函数中移到初始化的useEffect中全局注册,修改后的useEffect逻辑如下:
useEffect(() => { navigator.mediaDevices.getUserMedia({video: true, audio: true}) .then((stream)=>{ setStream(stream) myVideo.current.srcObject = stream }) .catch((err) => console.log(err)) socket.emit('join', ID) // 原有呼叫监听 socket.on("callUser", (data)=>{ setReceivingCall(true) setCaller(data.from) setCallerSignal(data.signal) }) // 新增全局呼叫接受监听 socket.on("callAccepted", (signal) => { console.log('call accepted!!') setCallAccepted(true) if(connectionRef.current) { connectionRef.current.signal(signal) } }) }, [])
随后删除callUser函数中原有的callAccepted监听代码即可。
修改完成后重启服务端,重新运行前端实例即可正常收到callAccepted事件,完成视频通话建联。
内容的提问来源于stack exchange,提问作者feychu
相关产品推荐
相关产品推荐

