我有以下react组件
function ConferencingRoom() {
const [participants, setParticipants] = useState({})
console.log('Participants -> ', participants)
useEffect(() => {
// messages handlers
socket.on('message', message => {
console.log('Message received: ' + message.event)
switch (message.event) {
case 'newParticipantArrived':
receiveVideo(message.userid, message.username)
break
case 'existingParticipants':
onExistingParticipants(
message.userid,
message.existingUsers
)
break
case 'receiveVideoAnswer':
onReceiveVideoAnswer(message.senderid, message.sdpAnswer)
break
case 'candidate':
addIceCandidate(message.userid, message.candidate)
break
default:
break
}
})
return () => {}
}, [participants])
// Socket Connetction handlers functions
const onExistingParticipants = (userid, existingUsers) => {
console.log('onExistingParticipants Called!!!!!')
//Add local User
const user = {
id: userid,
username: userName,
published: true,
rtcPeer: null
}
setParticipants(prevParticpants => ({
...prevParticpants,
[user.id]: user
}))
existingUsers.forEach(function(element) {
receiveVideo(element.id, element.name)
})
}
const onReceiveVideoAnswer = (senderid, sdpAnswer) => {
console.log('participants in Receive answer -> ', participants)
console.log('***************')
// participants[senderid].rtcPeer.processAnswer(sdpAnswer)
}
const addIceCandidate = (userid, candidate) => {
console.log('participants in Receive canditate -> ', participants)
console.log('***************')
// participants[userid].rtcPeer.addIceCandidate(candidate)
}
const receiveVideo = (userid, username) => {
console.log('Received Video Called!!!!')
//Add remote User
const user = {
id: userid,
username: username,
published: false,
rtcPeer: null
}
setParticipants(prevParticpants => ({
...prevParticpants,
[user.id]: user
}))
}
//Callback for setting rtcPeer after creating it in child component
const setRtcPeerForUser = (userid, rtcPeer) => {
setParticipants(prevParticpants => ({
...prevParticpants,
[userid]: { ...prevParticpants[userid], rtcPeer: rtcPeer }
}))
}
return (
<div id="meetingRoom">
{Object.values(participants).map(participant => (
<Participant
key={participant.id}
participant={participant}
roomName={roomName}
setRtcPeerForUser={setRtcPeerForUser}
sendMessage={sendMessage}
/>
))}
</div>
)
}
它拥有的唯一状态是调用内部的参与者的哈希表,使用 useState 钩子来定义它。
然后我使用 useEffect 来监听聊天室的套接字事件,只有 4 个事件
然后在那之后,我根据服务器上的执行顺序为这些事件定义了 4 个回调处理程序
最后我有另一个回调函数,它被传递给列表中的每个子参与者,以便在子组件创建它的 rtcPeer 对象后,它将它发送给父级以在参与者的 hashTable 中的参与者对象上设置它
流程是这样的参与者加入房间 -> existingParticipants事件被调用 -> 本地参与者被创建并添加到参与者 hashTable 然后 -> recieveVideoAnswer和候选人被服务器多次发出,如您在屏幕截图中看到的
第一个事件状态为空,随后的两个事件在那里,然后再次为空,这种模式不断重复一个空状态,然后以下两个是正确的,我不知道状态发生了什么