p2p-network.html 5.7 KB

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