webrtc.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. ;(function(){
  2. var Gun = (typeof window !== "undefined")? window.Gun : require('../gun');
  3. Gun.on('opt', function(root){
  4. this.to.next(root);
  5. var opt = root.opt;
  6. if(root.once){ return }
  7. if(!Gun.Mesh){ return }
  8. if(false === opt.RTCPeerConnection){ return }
  9. var env;
  10. if(typeof window !== "undefined"){ env = window }
  11. if(typeof global !== "undefined"){ env = global }
  12. env = env || {};
  13. var rtcpc = opt.RTCPeerConnection || env.RTCPeerConnection || env.webkitRTCPeerConnection || env.mozRTCPeerConnection;
  14. var rtcsd = opt.RTCSessionDescription || env.RTCSessionDescription || env.webkitRTCSessionDescription || env.mozRTCSessionDescription;
  15. var rtcic = opt.RTCIceCandidate || env.RTCIceCandidate || env.webkitRTCIceCandidate || env.mozRTCIceCandidate;
  16. if(!rtcpc || !rtcsd || !rtcic){ return }
  17. opt.RTCPeerConnection = rtcpc;
  18. opt.RTCSessionDescription = rtcsd;
  19. opt.RTCIceCandidate = rtcic;
  20. opt.rtc = opt.rtc || {'iceServers': [
  21. {urls: 'stun:stun.l.google.com:19302'},
  22. {urls: "stun:stun.sipgate.net:3478"}/*,
  23. {urls: "stun:stun.stunprotocol.org"},
  24. {urls: "stun:stun.sipgate.net:10000"},
  25. {urls: "stun:217.10.68.152:10000"},
  26. {urls: 'stun:stun.services.mozilla.com'}*/
  27. ]};
  28. // TODO: Select the most appropriate stuns.
  29. // FIXME: Find the wire throwing ICE Failed
  30. // The above change corrects at least firefox RTC Peer handler where it **throws** on over 6 ice servers, and updates url: to urls: removing deprecation warning
  31. opt.rtc.dataChannel = opt.rtc.dataChannel || {ordered: false, maxRetransmits: 2};
  32. opt.rtc.sdp = opt.rtc.sdp || {mandatory: {OfferToReceiveAudio: false, OfferToReceiveVideo: false}};
  33. opt.announce = function(to){
  34. root.on('out', {rtc: {id: opt.pid, to:to}}); // announce ourself
  35. };
  36. var mesh = opt.mesh = opt.mesh || Gun.Mesh(root);
  37. root.on('create', function(at){
  38. this.to.next(at);
  39. setTimeout(opt.announce, 1);
  40. });
  41. root.on('in', function(msg){
  42. if(msg.rtc){ open(msg) }
  43. this.to.next(msg);
  44. });
  45. function open(msg){
  46. var rtc = msg.rtc, peer, tmp;
  47. if(!rtc || !rtc.id){ return }
  48. delete opt.announce[rtc.id]; /// remove after connect
  49. if(tmp = rtc.answer){
  50. if(!(peer = opt.peers[rtc.id] || open[rtc.id]) || peer.remoteSet){ return }
  51. return peer.setRemoteDescription(peer.remoteSet = new opt.RTCSessionDescription(tmp));
  52. }
  53. if(tmp = rtc.candidate){
  54. peer = opt.peers[rtc.id] || open[rtc.id] || open({rtc: {id: rtc.id}});
  55. return peer.addIceCandidate(new opt.RTCIceCandidate(tmp));
  56. }
  57. //if(opt.peers[rtc.id]){ return }
  58. if(open[rtc.id]){ return }
  59. (peer = new opt.RTCPeerConnection(opt.rtc)).id = rtc.id;
  60. var wire = peer.wire = peer.createDataChannel('dc', opt.rtc.dataChannel);
  61. open[rtc.id] = peer;
  62. wire.onclose = function(){
  63. delete open[rtc.id];
  64. mesh.bye(peer);
  65. //reconnect(peer);
  66. };
  67. wire.onerror = function(err){};
  68. wire.onopen = function(e){
  69. //delete open[rtc.id];
  70. mesh.hi(peer);
  71. }
  72. wire.onmessage = function(msg){
  73. if(!msg){ return }
  74. mesh.hear(msg.data || msg, peer);
  75. };
  76. peer.onicecandidate = function(e){ // source: EasyRTC!
  77. if(!e.candidate){ return }
  78. root.on('out', {'@': msg['#'], rtc: {candidate: e.candidate, id: opt.pid}});
  79. }
  80. peer.ondatachannel = function(e){
  81. var rc = e.channel;
  82. rc.onmessage = wire.onmessage;
  83. rc.onopen = wire.onopen;
  84. rc.onclose = wire.onclose;
  85. }
  86. if(tmp = rtc.offer){
  87. peer.setRemoteDescription(new opt.RTCSessionDescription(tmp));
  88. peer.createAnswer(function(answer){
  89. peer.setLocalDescription(answer);
  90. root.on('out', {'@': msg['#'], rtc: {answer: answer, id: opt.pid}});
  91. }, function(){}, opt.rtc.sdp);
  92. return;
  93. }
  94. peer.createOffer(function(offer){
  95. peer.setLocalDescription(offer);
  96. root.on('out', {'@': msg['#'], rtc: {offer: offer, id: opt.pid}});
  97. }, function(){}, opt.rtc.sdp);
  98. return peer;
  99. }
  100. });
  101. var noop = function(){};
  102. }());