This WebRTC tab chat demo works across tabs or windows in the same browser without a server: https://jsfiddle.net/f5y48hcd/ (I gave up making it work in a code snippet due to a SecurityError.)
Open the fiddle in two windows and try it out. For reference, here's the WebRTC code:
var pc = new RTCPeerConnection(), dc, enterPressed = e => e.keyCode == 13;
var connect = () => init(dc = pc.createDataChannel("chat"));
pc.ondatachannel = e => init(dc = e.channel);
var init = dc => {
dc.onopen = e => (dc.send("Hi!"), chat.select());
dc.onclose = e => log("Bye!");
dc.onmessage = e => log(e.data);
};
chat.onkeypress = e => {
if (!enterPressed(e)) return;
dc.send(chat.value);
log("> " + chat.value);
chat.value = "";
};
var sc = new localSocket(), send = obj => sc.send(JSON.stringify(obj));
var incoming = msg => msg.sdp &&
pc.setRemoteDescription(new RTCSessionDescription(msg.sdp))
.then(() => pc.signalingState == "stable" || pc.createAnswer()
.then(answer => pc.setLocalDescription(answer))
.then(() => send({ sdp: pc.localDescription })))
.catch(log) || msg.candidate &&
pc.addIceCandidate(new RTCIceCandidate(msg.candidate)).catch(log);
sc.onmessage = e => incoming(JSON.parse(e.data));
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState);
pc.onicecandidate = e => send({ candidate: e.candidate });
pc.onnegotiationneeded = e => pc.createOffer()
.then(offer => pc.setLocalDescription(offer))
.then(() => send({ sdp: pc.localDescription }))
.catch(log);
var log = msg => div.innerHTML += "<br>" + msg;
I use this for demoing WebRTC data channels. Note that the secret sauce is the localSocket.js that I wrote for this, which looks like this:
function localSocket() {
localStorage.a = localStorage.b = JSON.stringify([]);
this.index = 0;
this.interval = setInterval(() => {
if (!this.in) {
if (!JSON.parse(localStorage.a).length) return;
this.in = "a"; this.out = "b";
}
var arr = JSON.parse(localStorage[this.in]);
if (arr.length <= this.index) return;
if (this.onmessage) this.onmessage({ data: arr[this.index] });
this.index++;
}, 200);
setTimeout(() => this.onopen && this.onopen({}));
}
localSocket.prototype = {
send: function(msg) {
if (!this.out) {
this.out = "a"; this.in = "b";
}
var arr = JSON.parse(localStorage[this.out]);
arr.push(msg);
localStorage[this.out] = JSON.stringify(arr);
},
close: function() {
clearInterval(this.interval);
}
};
It basically uses localStorage to simulate web sockets locally between two tabs. If this is all you want to do, then you don't even need WebRTC data channels.
Disclaimer: It's not very robust, and relies on two pages being ready to communicate, so not production-ready by any means.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…