p2p-network.html 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <script src="../../bower_components/peerjs/peer.min.js"></script>
  2. <link rel="import" href="file-transfer-protocol.html">
  3. <dom-module id="p2p-network">
  4. <template>
  5. </template>
  6. <script>
  7. 'use strict';
  8. Polymer({
  9. is: 'p2p-network',
  10. properties: {
  11. me: {
  12. type: String
  13. }
  14. },
  15. attached: function() {
  16. this._connectedPeers = {};
  17. this._initCallbacks = [];
  18. this._unsendMsgs = {};
  19. window.onunload = window.onbeforeunload = function() {
  20. if (!!this._peer && !this._peer.destroyed) {
  21. this._peer.destroy();
  22. }
  23. }.bind(this);
  24. },
  25. initialize: function() {
  26. if (window.isActive) {
  27. clearInterval(this.reconnectTimer);
  28. this.reconnectTimer = undefined;
  29. var options;
  30. if (window.debug) {
  31. options = {
  32. host: window.location.hostname,
  33. port: 3002,
  34. path: 'peerjs'
  35. };
  36. } else {
  37. options = {
  38. host: 'snapdrop.net',
  39. port: 443,
  40. path: 'peerjs',
  41. secure: true
  42. };
  43. }
  44. this._peer = new Peer(this.me, options);
  45. this._peer.on('open', function(id) {
  46. console.log('My peer ID is: ' + id);
  47. this.set('me', id);
  48. this._peerOpen = true;
  49. this._initCallbacks.forEach(function(cb) {
  50. cb();
  51. });
  52. }.bind(this));
  53. this._peer.on('connection', this.connect.bind(this));
  54. this._peer.on('error', function(err) {
  55. console.error(err);
  56. //ugly hack to find out error type
  57. if (err.message.indexOf('Could not connect to peer') > -1) {
  58. delete this._connectedPeers[this.peer];
  59. return;
  60. }
  61. if (err.message.indexOf('Lost connection to server') > -1) {
  62. this._peer.destroy();
  63. this._reconnect();
  64. return;
  65. }
  66. }.bind(this));
  67. }
  68. },
  69. connect: function(c) {
  70. var peer = c.peer;
  71. if (c.label === 'file') {
  72. c.on('data', function(data) {
  73. console.log(data);
  74. var dataView = new Uint8Array(data.file);
  75. var dataBlob = new Blob([dataView]);
  76. this.fire('file-received', {
  77. from: peer,
  78. blob: dataBlob,
  79. name: data.name,
  80. });
  81. }.bind(this));
  82. }
  83. if (c.label === 'system') {
  84. c.on('data', function(data) {
  85. data.from = peer;
  86. this.fire('system-event', data);
  87. }.bind(this));
  88. }
  89. },
  90. connectToPeer: (function() {
  91. function request(requestedPeer, callback) {
  92. return function() {
  93. //system messages channel
  94. var s = this._peer.connect(requestedPeer, {
  95. label: 'system'
  96. });
  97. s.on('open', function() {
  98. this.connect(s);
  99. if (callback) {
  100. callback();
  101. }
  102. }.bind(this));
  103. s.on('error', function(err) {
  104. console.log(err);
  105. if (err.message.indexOf('Connection is not open') > -1) {
  106. console.err('Handle this error!!');
  107. }
  108. });
  109. //files channel
  110. var f = this._peer.connect(requestedPeer, {
  111. label: 'file',
  112. reliable: true
  113. });
  114. f.on('open', function() {
  115. this.connect(f);
  116. }.bind(this));
  117. f.on('error', function(err) {
  118. console.log(err);
  119. });
  120. };
  121. }
  122. return function(requestedPeer, callback) {
  123. if (this._peer.connections[requestedPeer]) {
  124. callback();
  125. return;
  126. }
  127. if (this._peerOpen) {
  128. request(requestedPeer, callback).bind(this)();
  129. } else {
  130. this._initCallbacks.push(request(requestedPeer, callback).bind(this));
  131. }
  132. };
  133. }()),
  134. _sendFile: function(peerId, file) {
  135. var conns = this._peer.connections[peerId];
  136. if (conns) {
  137. conns.forEach(function(conn) {
  138. if (conn.label === 'file') {
  139. conn.send(file);
  140. console.log('send file via WebRTC');
  141. }
  142. }.bind(this));
  143. }
  144. },
  145. _sendSystemEvent: function(peerId, msg) {
  146. var conns = this._peer.connections[peerId];
  147. if (conns) {
  148. conns.forEach(function(conn) {
  149. if (conn.label === 'system') {
  150. conn.send(msg);
  151. }
  152. }.bind(this));
  153. }
  154. },
  155. _reconnect: function(e) {
  156. //try to reconnect after 3s
  157. if (!this.reconnectTimer) {
  158. this.reconnectTimer = setInterval(this.initialize.bind(this), 3000);
  159. }
  160. }
  161. });
  162. </script>
  163. </dom-module>