peer.on('call') 永远不会被调用
Posted
技术标签:
【中文标题】peer.on(\'call\') 永远不会被调用【英文标题】:peer.on('calll') is never being calledpeer.on('call') 永远不会被调用 【发布时间】:2021-06-30 09:24:26 【问题描述】:对等 js 不工作
我只是在 NodeJs 和 ReactJs 中创建 peerjs 视频流应用程序
下面的代码工作正常,我可以创建新的对等点,open
事件也正常工作。
const peer = new Peer(undefined,
host:"/",
port:"5001"
);
peer.on('open',id=>
socket.emit('join-room', roomId,id);
)
在服务器端,每当发出'join-room'
事件时,服务器都会发出另一个事件'user-disconnected'
并将userId (peerjs)
传递给客户端。
// server.js
socket.on('join-room',(roomId,userId)=>
console.log(`user $userId joined $roomId`);
socket.join(roomId);
socket.to(roomId).emit('user-connected',userId);
socket.on('disconnect', () =>
socket.to(roomId).emit('user-disconnected', userId)
)
)
每当在客户端触发'user-connected'
时,我都会调用connectToNewUser
,并且到目前为止一切正常。
socket.on('user-connected',userId=>
console.log("New user connected...")
connectToNewUser(userId, stream)
);
错误
这是在控制台console.log('connectToNewUser',1222.....)
上记录的,没有错误。
但是,这个call.on('stream')
永远不会被调用
connectToNewUser(userId, stream)
console.log('connectToNewUser',userId)
const call = peer.call(userId, stream);
const video = getVideo();
call.on('stream', userVideoStream =>
// never called
console.log('connectToNewUser','on','stream')
addVideoStream(video, userVideoStream)
);
call.on('close', () =>
video.remove()
)
peers[userId] = call
call.on('stream')
从未被调用的原因是peer.on('call')
从未被调用。
peer.on('call', call =>
// never called
console.log('This peer is being called...');
call.answer(stream)
const video = getVideo();
call.on('stream', userVideoStream =>
console.log('This peer is being called...on-stream...');
addVideoStream(video, userVideoStream)
)
);
Github repo
【问题讨论】:
【参考方案1】:我也遇到了同样的问题,在 *** 上经历了 10 多个解决方案后,这是我的建议。
connectToNewUser() 在用户完成导航承诺之前被触发。
尝试修改为:
socket.on('user-connected',userId=>
console.log("New user connected...")
//connectToNewUser(userId, stream)
setTimeout(connectToNewUser,1000,userId,stream)
);
它对我有用。
【讨论】:
【参考方案2】:您的代码类似于我正在处理的项目。我在启动 peer
实例时遇到了麻烦。我不得不将它在我的组件树中上移一级,因为我正在做的事情导致重新渲染,并且正在重新创建 peer
实例,并使用新的 id
。
还要检查您创建套接字的位置。确保您的user-connected
事件正在useEffect()
中注册。
useEffect(() =>
videoSocket = initiateVideoSocket(roomId, username, peer.id);
// When a viewer connects, this event is emitted and the streamer will connect to the viewer.
videoSocket.on("user-connected", (roomId, viewerPeerId) =>
connectToNewViewer(viewerPeerId, videoStream);
);
, [videoStream]);
const viewerVideoSocket = initiateVideoSocket(
room,
props.username,
viewerPeerId
);
const viewerChatSocket = initiateChatSocket(room, props.username);
let streamerVideoDiv;
useEffect(() =>
viewerVideoSocket.emit(
"user-connected",
room,
props.username,
viewerPeerId
);
viewerPeer.on("call", (call) =>
call.answer();
call.on("stream", (stream) =>
streamerVideoDiv = document.getElementById("streamer-video");
const content = document.createElement("video");
content.srcObject = stream;
content.addEventListener("loadedmetadata", () =>
content.play();
);
streamerVideoDiv.append(content);
);
);
return () =>
disconnectSocket();
;
, []);
【讨论】:
peer.on('open',id=> socket.emit('join-room', roomId,id); )
这工作正常,这意味着对等方能够与服务器建立连接
对。因此,您的套接字正在发出 join-room
事件并且正在调用该函数。你能console.log()
你的peer
实例看看它是否工作正常吗?
是的,套接字正在发出 join-room
事件
另外,在connectToNewUser()
函数中,这已成功记录console.log('connectToNewUser',userId)
,但我认为此语句不起作用const call = peer.call(userId, stream)
如果有时间可以去repogithub.com/ats1999/conference【参考方案3】:
您的代码的唯一问题是您在客户端上初始化 peer.on("call") 事件之前从服务器发出用户连接事件,这最终导致新客户端错过此事件。 最好的解决方案是在初始化 peer.on("call",...) 事件后发出一个就绪事件。
peer.on('call', call =>
console.log('This peer is being called...');
call.answer(stream)
const video = getVideo();
call.on('stream', userVideoStream =>
console.log('This peer is being called...on-stream...');
addVideoStream(video, userVideoStream)
))
socket.emit("ready")`
然后在服务器端调用侦听器内的“用户连接”广播事件以获取“就绪”事件:
socket.on('join-room',(roomId,userId)=>
console.log(`user $userId joined $roomId`);
socket.join(roomId);
socket.on('ready',()=>
socket.broadcast.to(roomId).emit('user-connected',userId);
)
socket.on('disconnect', () =>
socket.to(roomId).emit('user-disconnected', userId)
))
这将在客户端准备好接收 peer.on("call". .. .) 事件
【讨论】:
【参考方案4】:我认为你的代码是这样的
const peer = new Peer(undefined,host:"/",port:"5001")
peer.on('open',id=>
socket.emit('join-room', roomId,id)
)
navigator.mediaDevices.getUserMedia(
video : true,
audio : true
).then( stream =>
socket.on('user-connected',userId=>
// call the new user and send our stream
);
peer.on('call',call=>
// pick up the call and send our stream
)
)
每当有新客户端加入时,就会创建一个新的对等对象,然后套接字发出 join-room
并且服务器将 user-connected
广播给所有其他客户端
所以现在当新用户加入所有其他客户端的user-connected
函数时,所有其他客户端都调用新客户端。
需要注意的一个关键点是 navigator.mediaDevices.getUserMedia(video : true,audio : true)
需要一些时间
因此,当一个新客户端加入时,所有其他客户端会立即呼叫新客户端,但接听呼叫的功能(即peer.on('call',call=>)
)可能尚未在新客户端上定义,这就是新客户端不响应的原因,因为它仍在设置其视频流
要解决此问题,您必须在设置视频流后加入房间 所以像这样的
navigator.mediaDevices.getUserMedia(
video : true,
audio : true
).then( stream =>
const peer = new Peer(undefined,host:"/",port:"5001")
peer.on('open',id=>
socket.emit('join-room', roomId,id)
)
socket.on('user-connected',userId=>
// call the new user and send our stream
);
peer.on('call',call=>
// pick up the call and send our stream
)
)
【讨论】:
【参考方案5】:这里 Peer 对象在 Camera 和/或 Mic 准备好使用之前创建。
navigator.mediaDevices.getUserMedia(
video: true,
audio: true
).then(stream =>
//peer.on('call')
)
peer.on('call')
只会在getUserMedia()
完成执行后被浏览器执行。
问题是您正在接收呼叫事件,但还没有处理程序准备好处理该事件。最好的解决方案是在媒体准备好使用后加入会议室。
navigator.mediaDevices.getUserMedia(
video: true,
audio: true
).then(stream =>
const myPeer = new Peer(undefined,
host: '/',
port: '3001'
)
myPeer.on('open', id =>
socket.emit('join-room', ROOM_ID, id)
)
myPeer.on('call', call => )
)
【讨论】:
以上是关于peer.on('call') 永远不会被调用的主要内容,如果未能解决你的问题,请参考以下文章
IOS:UITextInput 上的 Tokenizer 永远不会被调用
QAbstractItemModel data() 永远不会被调用