我参考以下文档在我的 Peer Communicate Web 应用程序中使用完美的协商模式进行构建:
我的网页内容如下:
<html>
<head>
<meta charset="UTF-8">
<title>WebRTC Caller</title>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
var peer=null;
var socket = io.connect();
var dc,pc,polite=false;
var localVideo,remoteVideo;
var makingOffer = false, ignoreOffer = false;
var configuration = {iceServers:
[{urls: "stun:stun.stunprotocol.org"},
{urls: "stun:stun.l.google.com:19302"},
{urls: "turn:numb.viagenie.ca", credential: "***", username: "***"}
]};
$( document ).ready(function() {
localVideo=document.getElementById("selfView");
remoteVideo=document.getElementById("remoteView");
});
function call() {
polite=true;
createConnection();
}
function createConnection(){
pc=new RTCPeerConnection(configuration);
pc.onnegotiationneeded=negotiationEventHandler;
pc.onicecandidate=iceCandidateEventHandler;
dc= pc.createDataChannel('chat');
}
function hangUp() {
dc.close();
pc.close();
}
function iceCandidateEventHandler(event){
if (event.candidate==null){
writeLog("All ICE Candidates are sent");
} else {
writeLog("Send ICE Candidate");
socket.emit('send',{candidate:event.candidate});
}
}
async function negotiationEventHandler(){
writeLog('Handle Negotitation');
try {
makingOffer = true;
await pc.setLocalDescription();
socket.emit("send",{ description: pc.localDescription });
} catch(err) {
writeLog(err);
} finally {
makingOffer = false;
}
}
function clearLog() {
chatelement = document.getElementById('logger');
chatelement.innerHTML='';
}
function writeLog(message) {
var logger=document.getElementById("logger");
logger.innerHTML=message+"<br>"+logger.innerHTML;
}
socket.on("receive",async (req)=>{
let ignoreOffer = false;
clearLog();
createConnection();
if (req.description){
const offerCollision = (req.description.type == "offer") &&
(makingOffer || pc.signalingState != "stable");
ignoreOffer = !polite && offerCollision;
if (ignoreOffer) {
return;
}
await pc.setRemoteDescription(req.description);
if (req.description.type =="offer") {
await pc.setLocalDescription();
socket.emit("send",{description: pc.localDescription});
}
} else {
if (req.candidate){
try {
if (pc.currentRemoteDescription){
await pc.addIceCandidate(req.candidate);
}
} catch(err) {
if (!ignoreOffer) {
throw err;
}
}
}
}
});
</script>
</head>
<body>
<table border=1>
<tr>
<td>
<h1> Self View </h1>
<video id="selfView" width="320" height="240" autoplay muted></video>
</td>
<td>
<h1> Remote View </h1>
<video id="remoteView" width="320" height="240" autoplay muted></video>
</td>
</tr>
<tr>
<td><button onclick="call()">Make A Call</button><button onclick="addMedia()">Add Media</button></td>
<td><button onclick="hangUp()">Hang Up</button></td>
</tr>
</table>
<div id="logger" style="border:1px solid black;width:100%;height:30%;overflow:scroll">
</div>
</body>
</html> Run Code Online (Sandbox Code Playgroud)
我的 node.js 服务器端代码如下:
var fs = require('fs');
var https = require('https');
var express = require('express');
var app = express();
var options = {
key: fs.readFileSync('private.key'),
ca: [fs.readFileSync('ca_bundle.crt')],
cert: fs.readFileSync('certificate.crt')
};
var serverPort = 443;
var server = https.createServer(options, app);
var io = require('socket.io')(server);
var userList=[];
app.use(express.static('public'));
io.on('connection', function(socket) {
console.log('new connection');
userList.push(socket.id);
socket.emit('message', 'This is a message from the dark side.');
});
io.on('connection', (socket) => {
console.log('a user connected@'+(new Date()));
socket.on("send",(req)=>{
console.log("Receive send request");
socket.broadcast.emit("receive", req);
});
socket.on('disconnect', () => {
console.log('user disconnected@'+(new Date()));
});
});
server.listen(serverPort, function() {
console.log('server up and running at %s port', serverPort);
});
Run Code Online (Sandbox Code Playgroud)
我用 2 个浏览器打开网页(1 个是 chrome,1 个是 firefox)。当我在chrome浏览器中点击“拨打电话”按钮时,chrome提示如下错误信息:
Uncaught (in promise) DOMException: Failed to execute 'setRemoteDescription' on 'RTCPeerConnection': Failed to set remote answer sdp: Called in wrong state: kStable
Run Code Online (Sandbox Code Playgroud)
当我在firefox浏览器中点击“拨打电话”按钮时,firefox提示如下错误信息:
InvalidStateError: Cannot set remote answer in state stable
Run Code Online (Sandbox Code Playgroud)
有什么问题?我该如何解决?
| 归档时间: |
|
| 查看次数: |
1962 次 |
| 最近记录: |