Kdyby jste se nekdo moc nudil, mam tu tip pro js chat, ktery vyuziva stun server, treba googlu.
Dole kod pro html chat pro firefox pres stun server. Ted je tam nastaveny prazdny server=null, takze je treba to spustit pro 2 lidi ve dvou oknech firefoxu. Jeden vytvari mistnost (hosting), ostatni se pripojuji (guest), jestli to chapu spravne.
Okno1 - vytvorit channel (vygeneruje kod)
Okno1 - zkopirovat JSON kod z textarea u join do schranky
Okno2 - vlozit JSON kod ze schranky a kliknut na join (vygeneruje kod)
Okno2 - zkopirovat kod u ansfer
Okno1 - vlozit kod ansfer a kliknut na ansfer
A ted je mozne si psat.
Dalo mi dost prace najit funkcni kod, ktery generuje vubec nejake session-description.
Googlem spis najdete videochat, nahravani z web-cam a pod, pomoci webRTC.
<html>
<!--
http://pastebin.com/g2YVvrRd
http://stackoverflow.com/…-datachannel
-->
<head>
<title>WebRTC Basic</title>
</head>
<body>
<header><h1>WebRTC Basic</h1></header>
<section>
<div id="info" class="disconnected">
you must first create or join a channel
</div>
<form id="signal" action="">
<p>
<label for="channel">channel: </label>
<input id="channel" type="text" value="test" />
<button id="create">create</button>
</p>
<p>
<label for="offer">offer: </label>
<textarea id="offer" rows="8" cols="60"></textarea>
<button id="join">join</button>
</p>
<p>
<label for="answer">answer: </label>
<textarea id="answer" rows="8" cols="60"></textarea>
<button id="submitAnswer" disabled>submit answer</button>
</p>
</form>
<form id="chat" action="" onsubmit="return false;">
<label for="message"> message: </label>
<input id="message" autocomplete="off" disabled />
<input type="button" id="send" disabled value="send">
</form>
<div id="messages"></div>
</section>
<!--script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script-->
<script type="text/javascript">
var host = null, guest = null;
//var PeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
//var IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
//var SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
var channelID;
var RTC = {};
RTC.conn = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;;
RTC.session = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription || window.msRTCSessionDescription;
RTC.candidate = window.RTCIceCandidate || window.mozRTCIceCandidate;
var cfg = {}
cfg.server = {};
//cfg.server.url = {url: ['stun:stun.l.google.com 19302']};
//cfg.server.url = {iceServers: [{url:'stun:stun.l.google.com 19302'}]};
cfg.server.url = null;
cfg.server.opt = null;
cfg.server.opt = {optional: [{'DtlsSrtpKeyAgreement': true}, {'RtpDataChannels': true}]};
function setChannelEvents(channel) {
channel.onmessage = function (event) {
var message = event.data || event;
console.log('** channel.onmessage: ', message);
$("messages").innerHTML += '<br>'+message;
};
channel.onopen = function () {
console.log('** channel.onopen');
// and finally we can do this
channel.send('hello world!');
$("messages").innerHTML += '<br>sending';
};
channel.onerror = function (err) {
console.error('** channel.onerror: ', err);
};
channel.onclose = function (err) {
console.log('** channel.onclose: ', err);
};
}
// ---------------------------------------------------------------------
// Host object creates the offer for a WebRTC session
function classHost(id) {
var self = this;
this.id = id;
this.peer = new RTC.conn(cfg.server.url,cfg.server.opt);
this.dataChannel = this.peer.createDataChannel(id, {
reliable: true
});
this.peer.onicecandidate = function (event) {
if (!event.candidate) { // when ice is complete, there is an event without a candidate (on Chrome anyhow)
console.log(self.peer);
self.offer = self.peer.localDescription;
self.cb(self.offer);
}
}
setChannelEvents(this.dataChannel);
}
classHost.prototype.createOffer = function (cb) {
var self = this;
this.peer.createOffer(function (offer) {
console.log('Host.peer.createOffer callback: ', offer);
self.cb = cb;
self.peer.setLocalDescription(offer, function () {
// We wait for ICE to complete before continuing
//self.offer = offer;
//cb(offer);
}, function (err) {
console.error(err);
});
}, function (err) {
console.error(err);
}, null);
}
classHost.prototype.setRemoteDescription = function (answer, cb) {
var self = this;
console.log('Host.setRemoteDescription: ', answer);
var _sd = new RTC.session(answer);
this.peer.setRemoteDescription(_sd, cb, function (err) {
console.error(err);
});
};
// ---------------------------------------------------------------------
// Guest object answers the offer from the host
function classGuest(id) {
this.id = id;
this.peer = new RTC.conn(cfg.server.url,cfg.server.opt);
this.dataChannel = this.peer.createDataChannel(id, {
reliable: true
});
var self = this;
this.peer.ondatachannel = function (event) {
console.log('Guest.peer.datachannel: ', event);
self.dataChannel = event.channel;
setChannelEvents(self.dataChannel);
};
this.peer.onicecandidate = function (event) {
if (!event.candidate) { // when ice is complete, there is an event without a candidate (on Chrome anyhow)
self.answer = self.peer.localDescription;
self.cb(self.answer);
}
}
}
classGuest.prototype.setRemoteDescription = function (offer, cb) {
var self = this;
var _desc = new RTC.session(offer);
console.log('Guest desc: ', _desc, offer);
this.peer.setRemoteDescription(_desc, function () {
self.offer = offer;
cb();
}, function (err) {
console.error(err);
});
};
classGuest.prototype.createAnswer = function (cb) {
var self = this;
this.peer.createAnswer(function (answer) {
console.log('Guest.peer.createAnswer callback: ', answer);
self.answer = answer;
self.cb = cb;
self.peer.setLocalDescription(answer, function () {
// Again, waiting for ICE
//cb(answer);
}, function (err) {
console.error(err);
});
}, function (err) {
console.error(err);
});
};
// ---------------------------------------------------------------------
//alert(JSON);
function $(id)
{return document.getElementById(id);}
// $('document').ready(function () {
$("create").onclick = function () {
$("join").disabled = true;
$("submitAnswer").disabled = false;
channelID = $("channel").value;
host = new classHost(channelID);
host.createOffer(function (offer) {
$('offer').value = JSON.stringify(offer);
})
return false;
};
$("join").onclick = function () {
//$("#create").attr("disabled", "disabled");
//$("#submitAnswer").attr("disabled", "disabled");
$("create").disabled = true;
$("submitAnswer").disabled = false;
channelID = $("channel").value;
offer = $("offer").value;
guest = new classGuest(channelID);
guest.setRemoteDescription(JSON.parse(offer), function () {
console.log('Guest.setRemoteDescription completed');
guest.createAnswer(function (answer) {
$("answer").value = JSON.stringify(answer);
});
// guest.dataChannel.send('Guest joined');
$("message").disabled = false;
$("send").disabled = false;
});
return false;
};
$("submitAnswer").onclick = function () {
var answer = $("answer").value;
host.setRemoteDescription(JSON.parse(answer), function () {
console.log('-- complete');
// We wait before the data channel is set up, before we transmit anything (peer.onremotedatachannel)
//host.dataChannel.send('hello world!');
});
// host.dataChannel.send('Host joined');
$("message").disabled = false;
$("send").disabled = false;
return false;
};
$("send").onclick = function () {
var message = $("message").value;
var name = host && host.id ? 'host' : (guest && guest.id ? 'guest' : 'unknown')
$("messages").innerHTML += '<br>'+name+'> '+message;
if (host && host.id) {host.dataChannel.send(name+'> ' + message);}
if (guest && guest.id) {guest.dataChannel.send(name+'> ' + message);}
return false;
};
// });
/*
$(document).ready(function () {
$("#create").click(function () {
$("#join").attr("disabled", "disabled");
$("#submitAnswer").removeAttr("disabled");
channelID = $("#channel").val();
host = new Host(channelID);
host.createOffer(function (offer) {
$('#offer').val(JSON.stringify(offer));
})
return false;
});
$("#join").click(function () {
$("#create").attr("disabled", "disabled");
$("#submitAnswer").attr("disabled", "disabled");
channelID = $("#channel").val();
offer = $("#offer").val();
guest = new Guest(channelID);
guest.setRemoteDescription(JSON.parse(offer), function () {
console.log('Guest.setRemoteDescription completed');
guest.createAnswer(function (answer) {
$("#answer").val(JSON.stringify(answer));
});
});
return false;
});
$("#submitAnswer").click(function () {
var answer = $("#answer").val();
host.setRemoteDescription(JSON.parse(answer), function () {
console.log('-- complete');
// We wait before the data channel is set up, before we transmit anything (peer.onremotedatachannel)
//host.dataChannel.send('hello world!');
});
return false;
});
});
*/
</script>
</body>
</html>