gpt4 book ai didi

javascript - 实现信令的工作 Hello World WebRTC DataChannel 示例

转载 作者:可可西里 更新时间:2023-11-01 02:44:40 24 4
gpt4 key购买 nike

目的是让它成为一个 Community Wiki帖子保持最新,因此有兴趣使用 WebRTC DataChannels 实现 JSON 消息浏览器到浏览器 (p2p) 通信的开发人员有简单而实用的示例。

WebRTC DataChannels 是实验性的,仍处于草案阶段。目前看来,网络是过时的 WebRTC 示例的雷区,如果开发人员正在尝试学习 RTCDataChannel API,则更是如此。

如今可在 WebRTC 中使用的简单而实用的单页示例 compliant browsers似乎很难找到。例如,some examples省略信令实现,others仅适用于单个浏览器(例如 Chrome-Chrome),many由于最近的 API 更改而过时,并且 others非常复杂,它们对入门造成了障碍。

请发布满足以下条件的示例(如果不满足,请说明):

  1. 客户端代码为 1 页(200 行或更少)
  2. 服务端代码一页,技术引用(如node.js、php、python等)
  3. 实现了信令机制并引用了协议(protocol)技术(例如 WebSockets、long pollingGCM 等)
  4. 运行跨浏览器(Chrome、Firefox、Opera 和/或 Bowser)的工​​作代码
  5. 最少的选项,错误处理,abstraction等——意图是一个基本的例子

最佳答案

这是一个使用 HTML5 WebSockets 发送信号和 node.js 后端的工作示例

信号技术:WebSockets
客户端:纯 html/javascript
服务器:node.js , ws
最后测试:Firefox 40.0.2Chrome 44.0.2403.157 mOpera 31.0.1889.174


客户端代码:

<html>
<head>
</head>
<body>
<p id='msg'>Click the following in different browser windows</p>
<button type='button' onclick='init(false)'>I AM Answerer Peer (click first)</button>
<button type='button' onclick='init(true)'>I AM Offerer Peer</button>

<script>
(function() {
var offererId = 'Gandalf', // note: client id conflicts can happen
answererId = 'Saruman', // no websocket cleanup code exists
ourId, peerId,
RTC_IS_MOZILLA = !!window.mozRTCPeerConnection,
RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection || window.msRTCPeerConnection,
RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.msRTCSessionDescription,
RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.msRTCIceCandidate,
rtcpeerconn = new RTCPeerConnection(
{iceServers: [{ 'url': 'stun:stun.services.mozilla.com'}, {'url': 'stun:stun.l.google.com:19302'}]},
{optional: [{RtpDataChannels: false}]}
),
rtcdatachannel,
websocket = new WebSocket('ws://' + window.location.hostname + ':8000'),
comready, onerror;

window.init = function(weAreOfferer) {
ourId = weAreOfferer ? offererId : answererId;
peerId = weAreOfferer ? answererId : offererId;

websocket.send(JSON.stringify({
inst: 'init',
id: ourId
}));

if(weAreOfferer) {

rtcdatachannel = rtcpeerconn.createDataChannel(offererId+answererId);
rtcdatachannel.onopen = comready;
rtcdatachannel.onerror = onerror;

rtcpeerconn.createOffer(function(offer) {
rtcpeerconn.setLocalDescription(offer, function() {
var output = offer.toJSON();
if(typeof output === 'string') output = JSON.parse(output); // normalize: RTCSessionDescription.toJSON returns a json str in FF, but json obj in Chrome

websocket.send(JSON.stringify({
inst: 'send',
peerId: peerId,
message: output
}));
}, onerror);
}, onerror);
}
};

rtcpeerconn.ondatachannel = function(event) {
rtcdatachannel = event.channel;
rtcdatachannel.onopen = comready;
rtcdatachannel.onerror = onerror;
};

websocket.onmessage = function(input) {
var message = JSON.parse(input.data);

if(message.type && message.type === 'offer') {
var offer = new RTCSessionDescription(message);

rtcpeerconn.setRemoteDescription(offer, function() {
rtcpeerconn.createAnswer(function(answer) {
rtcpeerconn.setLocalDescription(answer, function() {
var output = answer.toJSON();
if(typeof output === 'string') output = JSON.parse(output); // normalize: RTCSessionDescription.toJSON returns a json str in FF, but json obj in Chrome

websocket.send(JSON.stringify({
inst: 'send',
peerId: peerId,
message: output
}));
}, onerror);
}, onerror);
}, onerror);
} else if(message.type && message.type === 'answer') {
var answer = new RTCSessionDescription(message);
rtcpeerconn.setRemoteDescription(answer, function() {/* handler required but we have nothing to do */}, onerror);
} else if(rtcpeerconn.remoteDescription) {
// ignore ice candidates until remote description is set
rtcpeerconn.addIceCandidate(new RTCIceCandidate(message.candidate));
}
};

rtcpeerconn.onicecandidate = function (event) {
if (!event || !event.candidate) return;
websocket.send(JSON.stringify({
inst: 'send',
peerId: peerId,
message: {candidate: event.candidate}
}));
};

/** called when RTC signaling is complete and RTCDataChannel is ready */
comready = function() {
rtcdatachannel.send('hello world!');
rtcdatachannel.onmessage = function(event) {
document.getElementById('msg').innerHTML = 'RTCDataChannel peer ' + peerId + ' says: ' + event.data;
}
};

/** global error function */
onerror = websocket.onerror = function(e) {
console.log('====== WEBRTC ERROR ======', arguments);
document.getElementById('msg').innerHTML = '====== WEBRTC ERROR ======<br>' + e;
throw new Error(e);
};
})();
</script>
</body>
</html>

服务器端代码:

var server = require('http').createServer(), 
express = require('express'),
app = express(),
WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ server: server, port: 8000 });

app.use(express.static(__dirname + '/static')); // client code goes in static directory

var clientMap = {};

wss.on('connection', function (ws) {
ws.on('message', function (inputStr) {
var input = JSON.parse(inputStr);
if(input.inst == 'init') {
clientMap[input.id] = ws;
} else if(input.inst == 'send') {
clientMap[input.peerId].send(JSON.stringify(input.message));
}
});
});

server.on('request', app);
server.listen(80, YOUR_HOSTNAME_OR_IP_HERE, function () { console.log('Listening on ' + server.address().port) });

关于javascript - 实现信令的工作 Hello World WebRTC DataChannel 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32172627/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com