问题描述
我正在尝试使用React
,webRTC
和socket.io-client
创建一个simple-peer
网络聊天平台。我遵循了一个教程并使用了他们的代码,但我不断收到此错误。
该错误大约每秒钟发生一次,我不确定为什么。
这是我在Room.js
中导入的组件(App.js
)的代码:
import React,{ useEffect,useState,useRef } from 'react';
import '../App.css';
import io from "socket.io-client";
import Peer from "simple-peer";
import styled from "styled-components";
const Container = styled.div`
height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
`;
const Row = styled.div`
display: flex;
width: 100%;
`;
const Video = styled.video`
border: 1px solid blue;
width: 50%;
height: 50%;
`;
function Room() {
const [yourID,setYourID] = useState("");
const [users,setUsers] = useState({});
const [stream,setStream] = useState();
const [receivingCall,setReceivingCall] = useState(false);
const [caller,setCaller] = useState("");
const [callerSignal,setCallerSignal] = useState();
const [callAccepted,setCallAccepted] = useState(false);
const userVideo = useRef();
const partnerVideo = useRef();
const socket = useRef();
useEffect(() => {
socket.current = io.connect("/");
navigator.mediaDevices.getUserMedia({ video: true,audio: true }).then(stream => {
setStream(stream);
if (userVideo.current) {
userVideo.current.srcObject = stream;
}
})
socket.current.on("yourID",(id) => {
setYourID(id);
})
socket.current.on("allUsers",(users) => {
setUsers(users);
})
socket.current.on("hey",(data) => {
setReceivingCall(true);
setCaller(data.from);
setCallerSignal(data.signal);
})
},[]);
function callPeer(id) {
const peer = new Peer({
initiator: true,trickle: false,config: {
iceServers: [
{
urls: "stun:numb.viagenie.ca",username: "[email protected]",credential: "98376683"
},{
urls: "turn:numb.viagenie.ca",credential: "98376683"
}
]
},stream: stream,});
peer.on("signal",data => {
socket.current.emit("callUser",{ userToCall: id,signalData: data,from: yourID })
})
peer.on("stream",stream => {
if (partnerVideo.current) {
partnerVideo.current.srcObject = stream;
}
});
socket.current.on("callAccepted",signal => {
setCallAccepted(true);
peer.signal(signal);
})
}
function acceptCall() {
setCallAccepted(true);
const peer = new Peer({
initiator: false,});
peer.on("signal",data => {
socket.current.emit("acceptCall",{ signal: data,to: caller })
})
peer.on("stream",stream => {
partnerVideo.current.srcObject = stream;
});
peer.signal(callerSignal);
}
let UserVideo;
if (stream) {
UserVideo = (
<Video playsInline muted ref={userVideo} autoplay />
);
}
let PartnerVideo;
if (callAccepted) {
PartnerVideo = (
<Video playsInline ref={partnerVideo} autoplay />
);
}
let incomingCall;
if (receivingCall) {
incomingCall = (
<div>
<h1>{caller} is calling you</h1>
<button onClick={acceptCall}>Accept</button>
</div>
)
}
return (
<Container>
<Row>
{UserVideo}
{PartnerVideo}
</Row>
<Row>
{Object.keys(users).map(key => {
if (key === yourID) {
return null;
}
return (
<button onClick={() => callPeer(key)}>Call {key}</button>
);
})}
</Row>
<Row>
{incomingCall}
</Row>
</Container>
);
}
export default Room;
这是我的App.js
文件:
import React from 'react';
import { browserRouter as Router,Route,Switch } from 'react-router-dom'
import './App.css';
import { ApolloProvider } from '@apollo/react-hooks';
import ApolloClient from 'apollo-boost';
import coverImg from './assets/videochat.jpg';
//components
import Room from './pages/Room';
import Cover from './components/Cover'
const client = new ApolloClient({
request: operation => {
const token = localStorage.getItem('User_token');
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : ''
}
});
},uri: '/graphql'
});
function App() {
return (
<ApolloProvider client={client}>
<Router>
<>
<Navbar />
<Switch>
<Route exact path="/" component={Cover}/>
<Route path='/create-room' component={Room} />
</Switch>
</>
</Router>
</ApolloProvider>
);
}
export default App;
然后是我的server.js
文件:
// const express = require('express')
// const app = express()
// const server = require('http').Server(app)
// const io = require('socket.io')(server)
// const { v4: uuidV4 } = require('uuid')
// app.set('view engine','ejs')
// app.use(express.static('public'))
// app.get('/create-room',(req,res) => {
// console.log("does this work")
// res.redirect(`/${uuidV4()}`)
// })
// app.get('/:room',res) => {
// res.render('../client/src/pages/room',{ roomId: req.params.room })
// })
// io.on('connection',socket => {
// socket.on('join-room',(roomId,userId) => {
// if (!person[socket.id]) {
// person[socket.id] = socket.id;
// }
// socket.emit("yourID",socket.id);
// io.sockets.emit("allUsers",person);
// socket.on("disconnect",() => {
// delete person[socket.id];
// });
// socket.on("callUser",(data) => {
// io.to(data.userToCall).emit("hey",{
// signal: data.signalData,// from: data.from,// });
// });
// socket.on("acceptCall",(data) => {
// io.to(data.to).emit("callAccepted",data.signal);
// });
// socket.join(roomId)
// socket.to(roomId).broadcast.emit('user-connected',userId)
// socket.on('disconnect',() => {
// socket.to(roomId).broadcast.emit('user-disconnected',userId)
// })
// })
// })
// server.listen(3000)
const express = require("express");
const http = require("http");
const app = express();
const server = http.createServer(app);
const socket = require("socket.io");
const io = socket(server);
const users = {};
io.on('connection',socket => {
if (!users[socket.id]) {
users[socket.id] = socket.id;
}
socket.emit("yourID",socket.id);
io.sockets.emit("allUsers",users);
socket.on('disconnect',() => {
delete users[socket.id];
})
socket.on("callUser",(data) => {
io.to(data.userToCall).emit('hey',{signal: data.signalData,from: data.from});
})
socket.on("acceptCall",(data) => {
io.to(data.to).emit('callAccepted',data.signal);
})
});
// For some reason the console.log is not printed either
server.listen(3000,() => console.log('server is running on port 3000'));
这是我的项目文件结构:
@H_404_24@project name
.env
package.json
package-lock.json
.gitignore
server
server.js
client
public
react-images
src
pages
Room.js
App.js
index.js
App.css
App.test.js
serviceWorker.js
setupTests.js
.gitIgnore
package.json
package-lock.js
README.md
解决方法
我能够找出我的错误,并考虑将其发布在这里,供将来的任何人使用。
在我的server.js
文件中,我需要它在另一个端口上运行,以便我的实际客户端代码在另一个端口上使用服务器。为此,您只需更改以下内容即可:
server.listen(3000,() => console.log('server is running on port 3000'));
对此:
server.listen(8000,() => console.log('server is running on port 8000'));
更改该行意味着您的服务器将在http:// localhost:8000上运行。我的另一个错误是我的客户端代码未链接到服务器,这意味着我在server.js
中编写的所有代码均与客户端代码无关。
要更改此设置,您必须在package.json
文件夹中的client
文件中添加一行。而不是这样:
{
"name": "client","version": "0.1.0","private": true,"dependencies": {
"@apollo/react-hooks": "^4.0.0",
将其更改为此:
{
"name": "client","proxy": "http://localhost:8000",
现在您的代码应该可以工作了!祝你好运!