为什么脚本显示对象内容不正确?



下面是我的客户端代码:

import {useEffect,useState} from 'react';
import io from 'socket.io-client';
import Peer from './Peer';
export default function TestMeeting(){
let peerName;
const [peerList,setPeerList]=useState({});
const [signalSocket,setSignalSocket]=useState(io.connect(process.env.REACT_APP_SOCKET_URL+"testMeeting", { transports: ['websocket'] }));
let sUsrAg = navigator.userAgent;
if (sUsrAg.indexOf("Edg")>-1){
peerName="Edge";
}else{
if (sUsrAg.indexOf("Chrome")>-1){
peerName="Chrome";
}else {
if (sUsrAg.indexOf("Firefox")>-1){
peerName="Firefox";
} else {
if (sUsrAg.indexOf("Safari")>-1){
peerName="Safari";
}
}
}
}
useEffect(()=>{
signalSocket.on("greeting",greeting=>{
let peer=new Peer(greeting.from,greeting.socketId);        
let temp={...peerList};
temp[greeting.socketId]=peer;
setPeerList(temp);
})
signalSocket.on("newPeerAdded",(remotePeer)=>{
let peer=new Peer(remotePeer.from,remotePeer.socketId);
peerList[remotePeer.socketId]=peer;
let temp={...peerList};
temp[remotePeer.socketId]=peer;
setPeerList(temp);
signalSocket.emit("sayHi",{socketId:remotePeer.socketId,"peerName":peerName});
});    
},[signalSocket,peerList,peerName])
let connect=()=>{
signalSocket.emit("newPeer",peerName);
}
console.log(peerList);
return(
<div>
<button onClick={connect}>Connect</button>
<div>
{
Object.keys(peerList).map((key,index) => (
<div key={index}>
{peerList[key].peerName()}
</div>
))
}  
</div>
</div>
);    
}
class Peer {
constructor(remotePeerName,remoteSocketId) {
let peerName=remotePeerName;
let socketId=remoteSocketId;
this.peerName=()=>{return peerName}
this.socketId=()=>{return socketId}
}
}
export default Peer;   

这是我的服务器端代码:

class TestMeeting{
constructor(socket){
console.log("TestMeeting:Connection established");
socket.on('disconnect', function () {
console.log("TestSimplePeer:Disconnected");
});
socket.on("newPeer",(peerName)=>{
console.log("TestMeeting:newPeer event received.")
socket.broadcast.emit("newPeerAdded", {from:peerName,socketId:socket.id});
});
socket.on("sayHi",(sayHi)=>{
console.log("sayHi event received.");
socket.to(sayHi.socketId).emit("greeting",{from:sayHi.peerName,socketId:socket.id});
});
}
}
module.exports=TestMeeting;

工作原理

当用户点击"连接"时按钮,它会发送"newPeer"事件通过服务器发送给其他对等点。其他同伴会回应"嗨"通过服务器发送带有套接字id的事件。

测试用例

我打开了3个浏览器来测试这些代码,所以当我点击"连接"按钮,我希望浏览器控制台应该显示以下内容:
Object { e_VLiK2A2ZrSS6uqAABn: {…} }                             TestMeeting.js:45
Object { e_VLiK2A2ZrSS6uqAABn: {…}, wjsYo70xzMWwkebkAABr: {…} }  TestMeeting.js:45

但是,浏览器控制台显示以下内容:

Object { e_VLiK2A2ZrSS6uqAABn: {…} }                             TestMeeting.js:45
Object { wjsYo70xzMWwkebkAABr: {…} }                             TestMeeting.js:45
Object { e_VLiK2A2ZrSS6uqAABn: {…}, wjsYo70xzMWwkebkAABr: {…} }  TestMeeting.js:45
你能告诉我发生了什么事吗?如何解决这个问题?

经过几次尝试,我成功了:

客户端代码:
import { useEffect, useReducer } from "react";
import io from "socket.io-client";
export default function TestMeeting() {
let peerName;
let sUsrAg = navigator.userAgent;
if (sUsrAg.indexOf("Edg") > -1) {
peerName = "Edge";
} else {
if (sUsrAg.indexOf("Chrome") > -1) {
peerName = "Chrome";
} else {
if (sUsrAg.indexOf("Firefox") > -1) {
peerName = "Firefox";
} else {
if (sUsrAg.indexOf("Safari") > -1) {
peerName = "Safari";
}
}
}
}
let socket=io.connect(process.env.REACT_APP_SOCKET_URL + "testMeeting", {
transports: ["websocket"],
})
const initialState = { 
peerList:{},
socket:socket
};
let reducer=(state,action)=>{
let result=null;
switch (action.type){
case "addPeer":
let temp={...state.peerList};
//console.log(state.peerList);
temp[action.peer.socketId]=action.peer;
result=result={...state,peerList:temp}
break;
case "initialPeerList":
result={...state,peerList:action.peerList}
break;
case "removePeer":
let temp1={...state.peerList};
delete temp1[action.socketId]
result=result={...state,peerList:temp1}
break;
default:
result=state;
break
}
return result;
}
useEffect(() => {
socket.emit("hi", peerName, (response) => {
console.log("=======================hi===============");
dispatch({type:"initialPeerList",peerList:response.peerList})
});
socket.on("newPeer", (peer) => {
dispatch({type:"addPeer",peer:peer})
});
socket.on("removePeer",(socketId)=>{
dispatch({type:"removePeer",socketId:socketId})
});  
},[]);
const [state, dispatch] = useReducer(reducer, initialState);
console.log(state);
return(
<>
{Object.keys(state.peerList).map((key, index) => (
<div key={index}>{state.peerList[key].name}</div>
))}        
</>
)
}
服务器端代码:
class TestMeeting{
constructor(){
let peerList={};
this.addPeer=(socket)=>{
socket.on('disconnect', function () {
let peer=peerList[socket.id];
console.log("TestSimplePeer:Disconnected");
if (peer){
console.log(peer.name+" leave the meeting.");
}
delete peerList[socket.id];
console.log("==================peer list===============");
console.log(peerList);
socket.broadcast.emit("removePeer",socket.id);
});
socket.on("hi",(peerName,calllBack)=>{
peerList[socket.id]={name:peerName,socketId:socket.id};
console.log("Received say hi from "+peerName+".");
socket.broadcast.emit("newPeer",peerList[socket.id]);
console.log("Broadcast newPeer ("+peerName+") to other peer.");
calllBack({"peerList":peerList})
})
}
}
}
module.exports=TestMeeting;

最新更新