File: source/skylink-events.js

  1. /**
  2. * Stores the list of <code>on()</code> event handlers.
  3. * @attribute _EVENTS
  4. * @param {Array} <#event> The list of event handlers associated with the event.
  5. * @param {Function} <#event>.<#index> The event handler function.
  6. * @type JSON
  7. * @private
  8. * @for Skylink
  9. * @since 0.5.2
  10. */
  11. Skylink.prototype._EVENTS = {
  12. /**
  13. * Event triggered when socket connection to Signaling server has opened.
  14. * @event channelOpen
  15. * @for Skylink
  16. * @since 0.1.0
  17. */
  18. channelOpen: [],
  19.  
  20. /**
  21. * Event triggered when socket connection to Signaling server has closed.
  22. * @event channelClose
  23. * @for Skylink
  24. * @since 0.1.0
  25. */
  26. channelClose: [],
  27.  
  28. /**
  29. * <blockquote class="info">
  30. * Note that this is used only for SDK developer purposes.
  31. * </blockquote>
  32. * Event triggered when receiving socket message from the Signaling server.
  33. * @event channelMessage
  34. * @param {JSON} message The socket message object.
  35. * @for Skylink
  36. * @since 0.1.0
  37. */
  38. channelMessage: [],
  39.  
  40. /**
  41. * <blockquote class="info">
  42. * This may be caused by Javascript errors in the event listener when subscribing to events.<br>
  43. * It may be resolved by checking for code errors in your Web App in the event subscribing listener.<br>
  44. * <code>skylinkDemo.on("eventName", function () { // Errors here });</code>
  45. * </blockquote>
  46. * Event triggered when socket connection encountered exception.
  47. * @event channelError
  48. * @param {Error|String} error The error object.
  49. * @for Skylink
  50. * @since 0.1.0
  51. */
  52. channelError: [],
  53.  
  54. /**
  55. * Event triggered when attempting to establish socket connection to Signaling server when failed.
  56. * @event channelRetry
  57. * @param {String} fallbackType The current fallback state.
  58. * [Rel: Skylink.SOCKET_FALLBACK]
  59. * @param {Number} currentAttempt The current reconnection attempt.
  60. * @for Skylink
  61. * @since 0.5.6
  62. */
  63. channelRetry: [],
  64.  
  65. /**
  66. * Event triggered when attempt to establish socket connection to Signaling server has failed.
  67. * @event socketError
  68. * @param {String} errorCode The socket connection error code.
  69. * [Rel: Skylink.SOCKET_ERROR]
  70. * @param {Error|String|Number} error The error object.
  71. * @param {String} type The fallback state of the socket connection attempt.
  72. * [Rel: Skylink.SOCKET_FALLBACK]
  73. * @for Skylink
  74. * @since 0.5.5
  75. */
  76. socketError: [],
  77.  
  78. /**
  79. * Event triggered when <a href="#method_init"><code>init()</code> method</a> ready state changes.
  80. * @event readyStateChange
  81. * @param {String} readyState The current <code>init()</code> ready state.
  82. * [Rel: Skylink.READY_STATE_CHANGE]
  83. * @param {JSON} [error] The error result.
  84. * <small>Defined only when <code>state</code> is <code>ERROR</code>.</small>
  85. * @param {Number} error.status The HTTP status code when failed.
  86. * @param {Number} error.errorCode The ready state change failure code.
  87. * [Rel: Skylink.READY_STATE_CHANGE_ERROR]
  88. * @param {Error} error.content The error object.
  89. * @param {String} room The Room to The Room to retrieve session token for.
  90. * @for Skylink
  91. * @since 0.4.0
  92. */
  93. readyStateChange: [],
  94.  
  95. /**
  96. * Event triggered when a Peer connection establishment state has changed.
  97. * @event handshakeProgress
  98. * @param {String} state The current Peer connection establishment state.
  99. * [Rel: Skylink.HANDSHAKE_PROGRESS]
  100. * @param {String} peerId The Peer ID.
  101. * @param {Error|String} [error] The error object.
  102. * <small>Defined only when <code>state</code> is <code>ERROR</code>.</small>
  103. * @for Skylink
  104. * @since 0.3.0
  105. */
  106. handshakeProgress: [],
  107.  
  108. /**
  109. * Event triggered when a Peer connection ICE gathering state has changed.
  110. * @event candidateGenerationState
  111. * @param {String} state The current Peer connection ICE gathering state.
  112. * [Rel: Skylink.CANDIDATE_GENERATION_STATE]
  113. * @param {String} peerId The Peer ID.
  114. * @for Skylink
  115. * @since 0.1.0
  116. */
  117. candidateGenerationState: [],
  118.  
  119. /**
  120. * Event triggered when a Peer connection session description exchanging state has changed.
  121. * @event peerConnectionState
  122. * @param {String} state The current Peer connection session description exchanging state.
  123. * [Rel: Skylink.PEER_CONNECTION_STATE]
  124. * @param {String} peerId The Peer ID.
  125. * @for Skylink
  126. * @since 0.1.0
  127. */
  128. peerConnectionState: [],
  129.  
  130. /**
  131. * Event triggered when a Peer connection ICE connection state has changed.
  132. * @event iceConnectionState
  133. * @param {String} state The current Peer connection ICE connection state.
  134. * [Rel: Skylink.ICE_CONNECTION_STATE]
  135. * @param {String} peerId The Peer ID.
  136. * @for Skylink
  137. * @since 0.1.0
  138. */
  139. iceConnectionState: [],
  140.  
  141. /**
  142. * Event triggered when retrieval of Stream failed.
  143. * @event mediaAccessError
  144. * @param {Error|String} error The error object.
  145. * @param {Boolean} isScreensharing The flag if event occurred during
  146. * <a href="#method_shareScreen"><code>shareScreen()</code> method</a> and not
  147. * <a href="#method_getUserMedia"><code>getUserMedia()</code> method</a>.
  148. * @param {Boolean} isAudioFallbackError The flag if event occurred during
  149. * retrieval of audio tracks only when <a href="#method_getUserMedia"><code>getUserMedia()</code> method</a>
  150. * had failed to retrieve both audio and video tracks.
  151. * @for Skylink
  152. * @since 0.1.0
  153. */
  154. mediaAccessError: [],
  155.  
  156. /**
  157. * Event triggered when Stream retrieval fallback state has changed.
  158. * @event mediaAccessFallback
  159. * @param {JSON} error The error result.
  160. * @param {Error|String} error.error The error object.
  161. * @param {JSON} [error.diff=null] The list of excepted but received audio and video tracks in Stream.
  162. * <small>Defined only when <code>state</code> payload is <code>FALLBACKED</code>.</small>
  163. * @param {JSON} error.diff.video The expected and received video tracks.
  164. * @param {Number} error.diff.video.expected The expected video tracks.
  165. * @param {Number} error.diff.video.received The received video tracks.
  166. * @param {JSON} error.diff.audio The expected and received audio tracks.
  167. * @param {Number} error.diff.audio.expected The expected audio tracks.
  168. * @param {Number} error.diff.audio.received The received audio tracks.
  169. * @param {Number} state The fallback state.
  170. * [Rel: Skylink.MEDIA_ACCESS_FALLBACK_STATE]
  171. * @param {Boolean} isScreensharing The flag if event occurred during
  172. * <a href="#method_shareScreen"><code>shareScreen()</code> method</a> and not
  173. * <a href="#method_getUserMedia"><code>getUserMedia()</code> method</a>.
  174. * @param {Boolean} isAudioFallback The flag if event occurred during
  175. * retrieval of audio tracks only when <a href="#method_getUserMedia"><code>getUserMedia()</code> method</a>
  176. * had failed to retrieve both audio and video tracks.
  177. * @param {String} streamId The Stream ID.
  178. * <small>Defined only when <code>state</code> payload is <code>FALLBACKED</code>.</small>
  179. * @for Skylink
  180. * @since 0.6.3
  181. */
  182. mediaAccessFallback: [],
  183.  
  184. /**
  185. * Event triggered when retrieval of Stream is successful.
  186. * @event mediaAccessSuccess
  187. * @param {MediaStream} stream The Stream object.
  188. * <small>To attach it to an element: <code>attachMediaStream(videoElement, stream);</code>.</small>
  189. * @param {Boolean} isScreensharing The flag if event occurred during
  190. * <a href="#method_shareScreen"><code>shareScreen()</code> method</a> and not
  191. * <a href="#method_getUserMedia"><code>getUserMedia()</code> method</a>.
  192. * @param {Boolean} isAudioFallback The flag if event occurred during
  193. * retrieval of audio tracks only when <a href="#method_getUserMedia"><code>getUserMedia()</code> method</a>
  194. * had failed to retrieve both audio and video tracks.
  195. * @param {String} streamId The Stream ID.
  196. * @for Skylink
  197. * @since 0.1.0
  198. */
  199. mediaAccessSuccess: [],
  200.  
  201. /**
  202. * Event triggered when retrieval of Stream is required to complete <a href="#method_joinRoom">
  203. * <code>joinRoom()</code> method</a> request.
  204. * @event mediaAccessRequired
  205. * @for Skylink
  206. * @since 0.5.5
  207. */
  208. mediaAccessRequired: [],
  209.  
  210. /**
  211. * Event triggered when Stream has stopped streaming.
  212. * @event mediaAccessStopped
  213. * @param {Boolean} isScreensharing The flag if event occurred during
  214. * <a href="#method_shareScreen"><code>shareScreen()</code> method</a> and not
  215. * <a href="#method_getUserMedia"><code>getUserMedia()</code> method</a>.
  216. * @param {Boolean} isAudioFallback The flag if event occurred during
  217. * retrieval of audio tracks only when <a href="#method_getUserMedia"><code>getUserMedia()</code> method</a>
  218. * had failed to retrieve both audio and video tracks.
  219. * @param {String} streamId The Stream ID.
  220. * @for Skylink
  221. * @since 0.5.6
  222. */
  223. mediaAccessStopped: [],
  224.  
  225. /**
  226. * Event triggered when a Peer joins the room.
  227. * @event peerJoined
  228. * @param {String} peerId The Peer ID.
  229. * @param {JSON} peerInfo The Peer session information.
  230. * @param {JSON|String} peerInfo.userData The Peer current custom data.
  231. * @param {JSON} peerInfo.settings The Peer sending Stream settings.
  232. * @param {Boolean|JSON} peerInfo.settings.audio The Peer Stream audio settings.
  233. * <small>When defined as <code>false</code>, it means there is no audio being sent from Peer.</small>
  234. * @param {Boolean} peerInfo.settings.audio.stereo The flag if stereo band is configured
  235. * when encoding audio codec is <a href="#attr_AUDIO_CODEC"><code>OPUS</code></a> for receiving audio data.
  236. * @param {Array} [peerInfo.settings.audio.optional] The Peer Stream <code>navigator.getUserMedia()</code> API
  237. * <code>audio: { optional [..] }</code> property.
  238. * @param {String} [peerInfo.settings.audio.deviceId] The Peer Stream audio track source ID of the device used.
  239. * @param {Boolean} peerInfo.settings.audio.exactConstraints The flag if Peer Stream audio track is sending exact
  240. * requested values of <code>peerInfo.settings.audio.deviceId</code> when provided.
  241. * @param {Boolean|JSON} peerInfo.settings.video The Peer Stream video settings.
  242. * <small>When defined as <code>false</code>, it means there is no video being sent from Peer.</small>
  243. * @param {JSON} peerInfo.settings.video.resolution The Peer Stream video resolution.
  244. * [Rel: Skylink.VIDEO_RESOLUTION]
  245. * @param {Number} peerInfo.settings.video.resolution.width The Peer Stream video resolution width.
  246. * @param {Number} peerInfo.settings.video.resolution.height The Peer Stream video resolution height.
  247. * @param {Number} [peerInfo.settings.video.frameRate] The Peer Stream video
  248. * <a href="https://en.wikipedia.org/wiki/Frame_rate">frameRate</a> per second (fps).
  249. * @param {Boolean} peerInfo.settings.video.screenshare The flag if Peer Stream is a screensharing Stream.
  250. * @param {Array} [peerInfo.settings.video.optional] The Peer Stream <code>navigator.getUserMedia()</code> API
  251. * <code>video: { optional [..] }</code> property.
  252. * @param {String} [peerInfo.settings.video.deviceId] The Peer Stream video track source ID of the device used.
  253. * @param {Boolean} peerInfo.settings.video.exactConstraints The flag if Peer Stream video track is sending exact
  254. * requested values of <code>peerInfo.settings.video.resolution</code>,
  255. * <code>peerInfo.settings.video.frameRate</code> and <code>peerInfo.settings.video.deviceId</code>
  256. * when provided.
  257. * @param {JSON} peerInfo.settings.bandwidth The maximum streaming bandwidth sent from Peer.
  258. * @param {Number} [peerInfo.settings.bandwidth.audio] The maximum audio streaming bandwidth sent from Peer.
  259. * @param {Number} [peerInfo.settings.bandwidth.video] The maximum video streaming bandwidth sent from Peer.
  260. * @param {Number} [peerInfo.settings.bandwidth.data] The maximum data streaming bandwidth sent from Peer.
  261. * @param {JSON} peerInfo.mediaStatus The Peer Stream muted settings.
  262. * @param {Boolean} peerInfo.mediaStatus.audioMuted The flag if Peer Stream audio tracks is muted or not.
  263. * <small>If Peer <code>peerInfo.settings.audio</code> is false, this will be defined as <code>true</code>.</small>
  264. * @param {Boolean} peerInfo.mediaStatus.videoMuted The flag if Peer Stream video tracks is muted or not.
  265. * <small>If Peer <code>peerInfo.settings.video</code> is false, this will be defined as <code>true</code>.</small>
  266. * @param {JSON} peerInfo.agent The Peer agent information.
  267. * @param {String} peerInfo.agent.name The Peer agent name.
  268. * <small>Data may be accessing browser or non-Web SDK name.</small>
  269. * @param {Number} peerInfo.agent.version The Peer agent version.
  270. * <small>Data may be accessing browser or non-Web SDK version.</small>
  271. * @param {String} [peerInfo.agent.os] The Peer platform name.
  272. * <small>Data may be accessing OS platform version from Web SDK.</small>
  273. * @param {String} [peerInfo.agent.pluginVersion] The Peer Temasys Plugin version.
  274. * <small>Defined only when Peer is using the Temasys Plugin (IE / Safari).</small>
  275. * @param {String} peerInfo.room The Room Peer is from.
  276. * @param {Boolean} isSelf The flag if Peer is User.
  277. * @for Skylink
  278. * @since 0.5.2
  279. */
  280. peerJoined: [],
  281.  
  282. /**
  283. * Event triggered when a Peer connection has been refreshed.
  284. * @event peerRestart
  285. * @param {String} peerId The Peer ID.
  286. * @param {JSON} peerInfo The Peer session information.
  287. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  288. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small>
  289. * @param {Boolean} isSelfInitiateRestart The flag if User is initiating the Peer connection refresh.
  290. * @for Skylink
  291. * @since 0.5.5
  292. */
  293. peerRestart: [],
  294.  
  295. /**
  296. * Event triggered when a Peer session information has been updated.
  297. * @event peerUpdated
  298. * @param {String} peerId The Peer ID.
  299. * @param {JSON} peerInfo The Peer session information.
  300. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  301. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small>
  302. * @param {Boolean} isSelf The flag if Peer is User.
  303. * @for Skylink
  304. * @since 0.5.2
  305. */
  306. peerUpdated: [],
  307.  
  308. /**
  309. * Event triggered when a Peer leaves the room.
  310. * @event peerLeft
  311. * @param {String} peerId The Peer ID.
  312. * @param {JSON} peerInfo The Peer session information.
  313. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  314. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small>
  315. * @param {Boolean} isSelf The flag if Peer is User.
  316. * @for Skylink
  317. * @since 0.5.2
  318. */
  319. peerLeft: [],
  320.  
  321. /**
  322. * Event triggered when Room session has ended abruptly due to network disconnections.
  323. * @event sessionDisconnect
  324. * @param {String} peerId The User's Room session Peer ID.
  325. * @param {JSON} peerInfo The User's Room session information.
  326. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  327. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small>
  328. * @for Skylink
  329. * @since 0.6.10
  330. */
  331. sessionDisconnect: [],
  332.  
  333. /**
  334. * Event triggered when receiving Peer Stream.
  335. * @event incomingStream
  336. * @param {String} peerId The Peer ID.
  337. * @param {MediaStream} stream The Stream object.
  338. * <small>To attach it to an element: <code>attachMediaStream(videoElement, stream);</code>.</small>
  339. * @param {Boolean} isSelf The flag if Peer is User.
  340. * @param {JSON} peerInfo The Peer session information.
  341. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  342. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small>
  343. * @for Skylink
  344. * @since 0.5.5
  345. */
  346. incomingStream: [],
  347.  
  348. /**
  349. * Event triggered when receiving message from Peer.
  350. * @event incomingMessage
  351. * @param {JSON} message The message result.
  352. * @param {JSON|String} message.content The message object.
  353. * @param {String} message.senderPeerId The sender Peer ID.
  354. * @param {String|Array} [message.targetPeerId=null] The value of the <code>targetPeerId</code>
  355. * defined in <a href="#method_sendP2PMessage"><code>sendP2PMessage()</code> method</a> or
  356. * <a href="#method_sendMessage"><code>sendMessage()</code> method</a>.
  357. * @param {Boolean} message.isPrivate The flag if message is targeted or not, basing
  358. * off the <code>targetPeerId</code> parameter being defined in
  359. * <a href="#method_sendP2PMessage"><code>sendP2PMessage()</code> method</a> or
  360. * <a href="#method_sendMessage"><code>sendMessage()</code> method</a>.
  361. * @param {Boolean} message.isDataChannel The flag if message is sent from
  362. * <a href="#method_sendP2PMessage"><code>sendP2PMessage()</code> method</a>.
  363. * @param {JSON} peerInfo The Peer session information.
  364. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  365. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small>
  366. * @param {Boolean} isSelf The flag if Peer is User.
  367. * @for Skylink
  368. * @since 0.5.2
  369. */
  370. incomingMessage: [],
  371.  
  372. /**
  373. * Event triggered when receiving completed data transfer from Peer.
  374. * @event incomingData
  375. * @param {Blob|String} data The data.
  376. * @param {String} transferId The data transfer ID.
  377. * @param {String} peerId The Peer ID.
  378. * @param {JSON} transferInfo The data transfer information.
  379. * <small>Object signature matches the <code>transferInfo</code> parameter payload received in the
  380. * <a href="#event_dataTransferState"><code>dataTransferState</code> event</a>.</small>
  381. * @param {Boolean} isSelf The flag if Peer is User.
  382. * @for Skylink
  383. * @since 0.6.1
  384. */
  385. incomingData: [],
  386.  
  387.  
  388. /**
  389. * Event triggered when receiving upload data transfer from Peer.
  390. * @event incomingDataRequest
  391. * @param {String} transferId The transfer ID.
  392. * @param {String} peerId The Peer ID.
  393. * @param {String} transferInfo The data transfer information.
  394. * <small>Object signature matches the <code>transferInfo</code> parameter payload received in the
  395. * <a href="#event_dataTransferState"><code>dataTransferState</code> event</a>.</small>
  396. * @param {Boolean} isSelf The flag if Peer is User.
  397. * @for Skylink
  398. * @since 0.6.1
  399. */
  400. incomingDataRequest: [],
  401.  
  402. /**
  403. * Event triggered when Room locked status has changed.
  404. * @event roomLock
  405. * @param {Boolean} isLocked The flag if Room is locked.
  406. * @param {JSON} peerInfo The Peer session information.
  407. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  408. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small>
  409. * @param {Boolean} isSelf The flag if User changed the Room locked status.
  410. * @for Skylink
  411. * @since 0.5.2
  412. */
  413. roomLock: [],
  414.  
  415. /**
  416. * Event triggered when a Datachannel connection state has changed.
  417. * @event dataChannelState
  418. * @param {String} state The current Datachannel connection state.
  419. * [Rel: Skylink.DATA_CHANNEL_STATE]
  420. * @param {String} peerId The Peer ID.
  421. * @param {Error} [error] The error object.
  422. * <small>Defined only when <code>state</code> payload is <code>ERROR</code>.</small>
  423. * @param {String} channelName The DataChannel ID.
  424. * @param {String} channelType The DataChannel type.
  425. * [Rel: Skylink.DATA_CHANNEL_TYPE]
  426. * @for Skylink
  427. * @since 0.1.0
  428. */
  429. dataChannelState: [],
  430.  
  431. /**
  432. * Event triggered when a data transfer state has changed.
  433. * @event dataTransferState
  434. * @param {String} state The current data transfer state.
  435. * [Rel: Skylink.DATA_TRANSFER_STATE]
  436. * @param {String} transferId The data transfer ID.
  437. * @param {String} peerId The Peer ID.
  438. * @param {JSON} transferInfo The data transfer information.
  439. * @param {Blob|String} [transferInfo.data] The data object.
  440. * <small>Defined only when <code>state</code> payload is <code>UPLOAD_STARTED</code> or
  441. * <code>DOWNLOAD_COMPLETED</code>.</small>
  442. * @param {String} transferInfo.name The data transfer name.
  443. * @param {Number} transferInfo.size The data transfer data object original size.
  444. * @param {String} transferInfo.dataType The data transfer session type.
  445. * [Rel: Skylink.DATA_TRANSFER_SESSION_TYPE]
  446. * @param {Number} transferInfo.timeout The flag if message is targeted or not, basing
  447. * off the <code>targetPeerId</code> parameter being defined in
  448. * <a href="#method_sendURLData"><code>sendURLData()</code> method</a> or
  449. * <a href="#method_sendBlobData"><code>sendBlobData()</code> method</a>.
  450. * @param {Boolean} transferInfo.isPrivate The flag if data transfer
  451. * @param {JSON} [error] The error result.
  452. * <small>Defined only when <code>state</code> payload is <code>ERROR</code> or <code>CANCEL</code>.</small>
  453. * @param {Error|String} error.message The error object.
  454. * @param {String} error.transferType The data transfer direction from where the error occurred.
  455. * [Rel: Skylink.DATA_TRANSFER_TYPE]
  456. * @for Skylink
  457. * @since 0.4.1
  458. */
  459. dataTransferState: [],
  460.  
  461. /**
  462. * Event triggered when Signaling server reaction state has changed.
  463. * @event systemAction
  464. * @param {String} action The current Signaling server reaction state.
  465. * [Rel: Skylink.SYSTEM_ACTION]
  466. * @param {String} message The message.
  467. * @param {String} reason The Signaling server reaction state reason of action code.
  468. * [Rel: Skylink.SYSTEM_ACTION_REASON]
  469. * @for Skylink
  470. * @since 0.5.1
  471. */
  472. systemAction: [],
  473.  
  474. /**
  475. * Event triggered when a server Peer joins the room.
  476. * @event serverPeerJoined
  477. * @param {String} peerId The Peer ID.
  478. * @param {String} serverPeerType The server Peer type
  479. * [Rel: Skylink.SERVER_PEER_TYPE]
  480. * @for Skylink
  481. * @since 0.6.1
  482. */
  483. serverPeerJoined: [],
  484.  
  485. /**
  486. * Event triggered when a server Peer leaves the room.
  487. * @event serverPeerLeft
  488. * @param {String} peerId The Peer ID.
  489. * @param {String} serverPeerType The server Peer type
  490. * [Rel: Skylink.SERVER_PEER_TYPE]
  491. * @for Skylink
  492. * @since 0.6.1
  493. */
  494. serverPeerLeft: [],
  495.  
  496. /**
  497. * Event triggered when a server Peer connection has been refreshed.
  498. * @event serverPeerRestart
  499. * @param {String} peerId The Peer ID.
  500. * @param {String} serverPeerType The server Peer type
  501. * [Rel: Skylink.SERVER_PEER_TYPE]
  502. * @for Skylink
  503. * @since 0.6.1
  504. */
  505. serverPeerRestart: [],
  506.  
  507. /**
  508. * Event triggered when Peer Stream streaming has stopped.
  509. * @event streamEnded
  510. * @param {String} peerId The Peer ID.
  511. * @param {JSON} peerInfo The Peer session information.
  512. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  513. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small>
  514. * @param {Boolean} isSelf The flag if Peer is User.
  515. * @param {Boolean} isScreensharing The flag if Peer Stream is a screensharing Stream.
  516. * @param {String} streamId The Stream ID.
  517. * @for Skylink
  518. * @since 0.5.10
  519. */
  520. streamEnded: [],
  521.  
  522. /**
  523. * Event triggered when Peer Stream audio or video tracks has been muted / unmuted.
  524. * @event streamMuted
  525. * @param {String} peerId The Peer ID.
  526. * @param {JSON} peerInfo The Peer session information.
  527. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  528. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small>
  529. * @param {Boolean} isSelf The flag if Peer is User.
  530. * @param {Boolean} isScreensharing The flag if Peer Stream is a screensharing Stream.
  531. * @for Skylink
  532. * @since 0.6.1
  533. */
  534. streamMuted: [],
  535.  
  536. /**
  537. * Event triggered when <a href="#method_getPeers"><code>getPeers()</code> method</a> retrieval state changes.
  538. * @event getPeersStateChange
  539. * @param {String} state The current <code>getPeers()</code> retrieval state.
  540. * [Rel: Skylink.GET_PEERS_STATE]
  541. * @param {String} privilegedPeerId The User's privileged Peer ID.
  542. * @param {JSON} peerList The list of Peer IDs Rooms within the same App space.
  543. * @param {Array} peerList.#room The list of Peer IDs associated with the Room defined in <code>#room</code> property.
  544. * @for Skylink
  545. * @since 0.6.1
  546. */
  547. getPeersStateChange: [],
  548.  
  549. /**
  550. * Event triggered when <a href="#method_introducePeer"><code>introducePeer()</code> method</a>
  551. * introduction request state changes.
  552. * @event introduceStateChange
  553. * @param {String} state The current <code>introducePeer()</code> introduction request state.
  554. * [Rel: Skylink.INTRODUCE_STATE]
  555. * @param {String} privilegedPeerId The User's privileged Peer ID.
  556. * @param {String} sendingPeerId The Peer ID to be connected with <code>receivingPeerId</code>.
  557. * @param {String} receivingPeerId The Peer ID to be connected with <code>sendingPeerId</code>.
  558. * @param {String} [reason] The error object.
  559. * <small>Defined only when <code>state</code> payload is <code>ERROR</code>.</small>
  560. * @for Skylink
  561. * @since 0.6.1
  562. */
  563. introduceStateChange: [],
  564.  
  565. /**
  566. * Event triggered when <a href="#method_getConnectionStatus"><code>getConnectionStatus()</code> method</a>
  567. * retrieval state changes.
  568. * @event getConnectionStatusStateChange
  569. * @param {Number} state The current <code>getConnectionStatus()</code> retrieval state.
  570. * [Rel: Skylink.GET_CONNECTION_STATUS_STATE]
  571. * @param {String} peerId The Peer ID.
  572. * @param {JSON} [stats] The Peer connection current stats.
  573. * <small>Defined only when <code>state</code> payload is <code>RETRIEVE_SUCCESS</code>.</small>
  574. * @param {JSON} stats.raw The Peer connection raw stats before parsing.
  575. * @param {JSON} stats.audio The Peer connection audio streaming stats.
  576. * @param {JSON} stats.audio.sending The Peer connection sending audio streaming stats.
  577. * @param {Number} stats.audio.sending.bytes The Peer connection sending audio streaming bytes.
  578. * @param {Number} stats.audio.sending.packets The Peer connection sending audio streaming packets.
  579. * @param {Number} stats.audio.sending.packetsLost The Peer connection sending audio streaming packets lost.
  580. * @param {Number} stats.audio.sending.ssrc The Peer connection sending audio streaming RTP packets SSRC.
  581. * @param {Number} stats.audio.sending.rtt The Peer connection sending audio streaming RTT (Round-trip delay time).
  582. * <small>Defined as <code>0</code> if it's not present in original raw stats before parsing.</small>
  583. * @param {JSON} stats.audio.receiving The Peer connection receiving audio streaming stats.
  584. * @param {Number} stats.audio.receiving.bytes The Peer connection sending audio streaming bytes.
  585. * @param {Number} stats.audio.receiving.packets The Peer connection receiving audio streaming packets.
  586. * @param {Number} stats.audio.receiving.packetsLost The Peer connection receiving audio streaming packets lost.
  587. * @param {Number} stats.audio.receiving.ssrc The Peer connection receiving audio streaming RTP packets SSRC.
  588. * @param {JSON} stats.video The Peer connection video streaming stats.
  589. * @param {JSON} stats.video.sending The Peer connection sending video streaming stats.
  590. * @param {Number} stats.video.sending.bytes The Peer connection sending video streaming bytes.
  591. * @param {Number} stats.video.sending.packets The Peer connection sending video streaming packets.
  592. * @param {Number} stats.video.sending.packetsLost The Peer connection sending video streaming packets lost.
  593. * @param {JSON} stats.video.sending.ssrc The Peer connection sending video streaming RTP packets SSRC.
  594. * @param {Number} stats.video.sending.rtt The Peer connection sending video streaming RTT (Round-trip delay time).
  595. * <small>Defined as <code>0</code> if it's not present in original raw stats before parsing.</small>
  596. * @param {JSON} stats.video.receiving The Peer connection receiving video streaming stats.
  597. * @param {Number} stats.video.receiving.bytes The Peer connection receiving video streaming bytes.
  598. * @param {Number} stats.video.receiving.packets The Peer connection receiving video streaming packets.
  599. * @param {Number} stats.video.receiving.packetsLost The Peer connection receiving video streaming packets lost.
  600. * @param {Number} stats.video.receiving.ssrc The Peer connection receiving video streaming RTP packets SSRC.
  601. * @param {JSON} stats.selectedCandidate The Peer connection selected ICE candidate pair stats.
  602. * @param {JSON} stats.selectedCandidate.local The Peer connection selected local ICE candidate.
  603. * @param {String} stats.selectedCandidate.local.ipAddress The Peer connection selected
  604. * local ICE candidate IP address.
  605. * @param {Number} stats.selectedCandidate.local.portNumber The Peer connection selected
  606. * local ICE candidate port number.
  607. * @param {String} stats.selectedCandidate.local.transport The Peer connection selected
  608. * local ICE candidate IP transport type.
  609. * @param {String} stats.selectedCandidate.local.candidateType The Peer connection selected
  610. * local ICE candidate type.
  611. * @param {JSON} stats.selectedCandidate.remote The Peer connection selected remote ICE candidate.
  612. * @param {String} stats.selectedCandidate.remote.ipAddress The Peer connection selected
  613. * remote ICE candidate IP address.
  614. * @param {Number} stats.selectedCandidate.remote.portNumber The Peer connection selected
  615. * remote ICE candidate port number.
  616. * @param {String} stats.selectedCandidate.remote.transport The Peer connection selected
  617. * remote ICE candidate IP transport type.
  618. * @param {String} stats.selectedCandidate.remote.candidateType The Peer connection selected
  619. * remote ICE candidate type.
  620. * @param {JSON} stats.connection The Peer connection object stats.
  621. * @param {String} stats.connection.iceConnectionState The Peer connection ICE connection state.
  622. * @param {String} stats.connection.iceGatheringState The Peer connection ICE gathering state.
  623. * @param {String} stats.connection.signalingState The Peer connection signaling state.
  624. * @param {JSON} stats.connection.localDescription The Peer connection local session description.
  625. * @param {String} stats.connection.localDescription.type The Peer connection local session description type.
  626. * @param {String} stats.connection.localDescription.sdp The Peer connection local session description SDP.
  627. * @param {JSON} stats.connection.remoteDescription The Peer connection remote session description.
  628. * @param {String} stats.connection.remoteDescription.type The Peer connection remote session description type.
  629. * @param {String} stats.connection.remoteDescription.sdp The Peer connection remote session description sdp.
  630. * @param {JSON} stats.connection.candidates The Peer connection list of ICE candidates sent or received.
  631. * @param {JSON} stats.connection.candidates.sending The Peer connection list of local ICE candidates sent.
  632. * @param {Array} stats.connection.candidates.sending.host The Peer connection list of local
  633. * <code>"host"</code> ICE candidates sent.
  634. * @param {Array} stats.connection.candidates.sending.srflx The Peer connection list of local
  635. * <code>"srflx"</code> ICE candidates sent.
  636. * @param {Array} stats.connection.candidates.sending.relay The Peer connection list of local
  637. * <code>"relay"</code> candidates sent.
  638. * @param {JSON} stats.connection.candidates.receiving The Peer connection list of remote ICE candidates received.
  639. * @param {Array} stats.connection.candidates.receiving.host The Peer connection list of remote
  640. * <code>"host"</code> ICE candidates received.
  641. * @param {Array} stats.connection.candidates.receiving.srflx The Peer connection list of remote
  642. * <code>"srflx"</code> ICE candidates received.
  643. * @param {Array} stats.connection.candidates.receiving.relay The Peer connection list of remote
  644. * <code>"relay"</code> ICE candidates received.
  645. * @param {Error} error The error object received.
  646. * <small>Defined only when <code>state</code> payload is <code>RETRIEVE_ERROR</code>.</small>
  647. * @for Skylink
  648. * @since 0.6.14
  649. */
  650. getConnectionStatusStateChange: [],
  651.  
  652. /**
  653. * Event triggered when <a href="#method_muteStream"><code>muteStream()</code> method</a> changes
  654. * User Streams audio and video tracks muted status.
  655. * @event localMediaMuted
  656. * @param {JSON} mediaStatus The Streams muted settings.
  657. * <small>This indicates the muted settings for both
  658. * <a href="#method_getUserMedia"><code>getUserMedia()</code> Stream</a> and
  659. * <a href="#method_shareScreen"><code>shareScreen()</code> Stream</a>.</small>
  660. * @param {Boolean} mediaStatus.audioMuted The flag if all Streams audio tracks is muted or not.
  661. * <small>If User's <code>peerInfo.settings.audio</code> is false, this will be defined as <code>true</code>.</small>
  662. * @param {Boolean} mediaStatus.videoMuted The flag if all Streams video tracks is muted or not.
  663. * <small>If User's <code>peerInfo.settings.video</code> is false, this will be defined as <code>true</code>.</small>
  664. * @for Skylink
  665. * @since 0.6.15
  666. */
  667. localMediaMuted: []
  668. };
  669.  
  670. /**
  671. * Stores the list of <code>once()</code> event handlers.
  672. * These events are only triggered once.
  673. * @attribute _onceEvents
  674. * @param {Array} <#event> The list of event handlers associated with the event.
  675. * @param {Array} <#event>.<#index> The array of event handler function and its condition function.
  676. * @type JSON
  677. * @private
  678. * @for Skylink
  679. * @since 0.5.4
  680. */
  681. Skylink.prototype._onceEvents = {};
  682.  
  683. /**
  684. * Stores the timestamps data used for throttling.
  685. * @attribute _timestamp
  686. * @type JSON
  687. * @private
  688. * @for Skylink
  689. * @since 0.5.8
  690. */
  691. Skylink.prototype._timestamp = {
  692. now: Date.now() || function() { return +new Date(); },
  693. screen: false
  694. };
  695.  
  696. /**
  697. * Function that subscribes a listener to an event.
  698. * @method on
  699. * @param {String} eventName The event.
  700. * @param {Function} callback The listener.
  701. * <small>This will be invoked when event is triggered.</small>
  702. * @example
  703. * // Example 1: Subscribing to "peerJoined" event
  704. * skylinkDemo.on("peerJoined", function (peerId, peerInfo, isSelf) {
  705. * console.info("peerJoined event has been triggered with:", peerId, peerInfo, isSelf);
  706. * });
  707. * @for Skylink
  708. * @since 0.1.0
  709. */
  710. Skylink.prototype.on = function(eventName, callback) {
  711. if ('function' === typeof callback) {
  712. this._EVENTS[eventName] = this._EVENTS[eventName] || [];
  713. this._EVENTS[eventName].push(callback);
  714. log.log([null, 'Event', eventName, 'Event is subscribed']);
  715. } else {
  716. log.error([null, 'Event', eventName, 'Provided parameter is not a function']);
  717. }
  718. };
  719.  
  720. /**
  721. * Function that subscribes a listener to an event once.
  722. * @method once
  723. * @param {String} eventName The event.
  724. * @param {Function} callback The listener.
  725. * <small>This will be invoked once when event is triggered and conditional function is satisfied.</small>
  726. * @param {Function} [condition] The conditional function that will be invoked when event is triggered.
  727. * <small>Return <code>true</code> when invoked to satisfy condition.</small>
  728. * <small>When not provided, the conditional function will always return <code>true</code>.</small>
  729. * @param {Boolean} [fireAlways=false] The flag that indicates if <code>once()</code> should act like
  730. * <code>on()</code> but only invoke listener only when conditional function is satisfied.
  731. * @example
  732. * // Example 1: Subscribing to "peerJoined" event that triggers without condition
  733. * skylinkDemo.once("peerJoined", function (peerId, peerInfo, isSelf) {
  734. * console.info("peerJoined event has been triggered once with:", peerId, peerInfo, isSelf);
  735. * });
  736. *
  737. * // Example 2: Subscribing to "incomingStream" event that triggers with condition
  738. * skylinkDemo.once("incomingStream", function (peerId, stream, isSelf, peerInfo) {
  739. * console.info("incomingStream event has been triggered with User stream:", stream);
  740. * }, function (peerId, peerInfo, isSelf) {
  741. * return isSelf;
  742. * });
  743. *
  744. * // Example 3: Subscribing to "dataTransferState" event that triggers always only when condition is satisfied
  745. * skylinkDemo.once("dataTransferState", function (state, transferId, peerId, transferInfo) {
  746. * console.info("Received data transfer from Peer:", transferInfo.data);
  747. * }, function (state, transferId, peerId) {
  748. * if (state === skylinkDemo.DATA_TRANSFER_STATE.UPLOAD_REQUEST) {
  749. * skylinkDemo.acceptDataTransfer(peerId, transferId);
  750. * }
  751. * return state === skylinkDemo.DATA_TRANSFER_STATE.DOWNLOAD_COMPLETED;
  752. * }, true);
  753. * @for Skylink
  754. * @since 0.5.4
  755. */
  756. Skylink.prototype.once = function(eventName, callback, condition, fireAlways) {
  757. if (typeof condition === 'boolean') {
  758. fireAlways = condition;
  759. condition = null;
  760. }
  761. fireAlways = (typeof fireAlways === 'undefined' ? false : fireAlways);
  762. condition = (typeof condition !== 'function') ? function () {
  763. return true;
  764. } : condition;
  765.  
  766. if (typeof callback === 'function') {
  767.  
  768. this._EVENTS[eventName] = this._EVENTS[eventName] || [];
  769. // prevent undefined error
  770. this._onceEvents[eventName] = this._onceEvents[eventName] || [];
  771. this._onceEvents[eventName].push([callback, condition, fireAlways]);
  772. log.log([null, 'Event', eventName, 'Event is subscribed on condition']);
  773. } else {
  774. log.error([null, 'Event', eventName, 'Provided callback is not a function']);
  775. }
  776. };
  777.  
  778. /**
  779. * Function that unsubscribes listeners from an event.
  780. * @method off
  781. * @param {String} eventName The event.
  782. * @param {Function} [callback] The listener to unsubscribe.
  783. * - When not provided, all listeners associated to the event will be unsubscribed.
  784. * @example
  785. * // Example 1: Unsubscribe all "peerJoined" event
  786. * skylinkDemo.off("peerJoined");
  787. *
  788. * // Example 2: Unsubscribe only one listener from "peerJoined event"
  789. * var pJListener = function (peerId, peerInfo, isSelf) {
  790. * console.info("peerJoined event has been triggered with:", peerId, peerInfo, isSelf);
  791. * };
  792. *
  793. * skylinkDemo.off("peerJoined", pJListener);
  794. * @for Skylink
  795. * @since 0.5.5
  796. */
  797. Skylink.prototype.off = function(eventName, callback) {
  798. if (callback === undefined) {
  799. this._EVENTS[eventName] = [];
  800. this._onceEvents[eventName] = [];
  801. log.log([null, 'Event', eventName, 'All events are unsubscribed']);
  802. return;
  803. }
  804. var arr = this._EVENTS[eventName];
  805. var once = this._onceEvents[eventName];
  806.  
  807. // unsubscribe events that is triggered always
  808. for (var i = 0; i < arr.length; i++) {
  809. if (arr[i] === callback) {
  810. log.log([null, 'Event', eventName, 'Event is unsubscribed']);
  811. arr.splice(i, 1);
  812. break;
  813. }
  814. }
  815. // unsubscribe events fired only once
  816. if(once !== undefined) {
  817. for (var j = 0; j < once.length; j++) {
  818. if (once[j][0] === callback) {
  819. log.log([null, 'Event', eventName, 'One-time Event is unsubscribed']);
  820. once.splice(j, 1);
  821. break;
  822. }
  823. }
  824. }
  825. };
  826.  
  827. /**
  828. * Function that triggers an event.
  829. * The rest of the parameters after the <code>eventName</code> parameter is considered as the event parameter payloads.
  830. * @method _trigger
  831. * @private
  832. * @for Skylink
  833. * @since 0.1.0
  834. */
  835. Skylink.prototype._trigger = function(eventName) {
  836. //convert the arguments into an array
  837. var args = Array.prototype.slice.call(arguments);
  838. var arr = this._EVENTS[eventName];
  839. var once = this._onceEvents[eventName] || null;
  840. args.shift(); //Omit the first argument since it's the event name
  841. if (arr) {
  842. // for events subscribed forever
  843. for (var i = 0; i < arr.length; i++) {
  844. try {
  845. log.log([null, 'Event', eventName, 'Event is fired']);
  846. if(arr[i].apply(this, args) === false) {
  847. break;
  848. }
  849. } catch(error) {
  850. log.error([null, 'Event', eventName, 'Exception occurred in event:'], error);
  851. throw error;
  852. }
  853. }
  854. }
  855. if (once){
  856. // for events subscribed on once
  857. for (var j = 0; j < once.length; j++) {
  858. if (once[j][1].apply(this, args) === true) {
  859. log.log([null, 'Event', eventName, 'Condition is met. Firing event']);
  860. if(once[j][0].apply(this, args) === false) {
  861. break;
  862. }
  863. if (!once[j][2]) {
  864. log.log([null, 'Event', eventName, 'Removing event after firing once']);
  865. once.splice(j, 1);
  866. //After removing current element, the next element should be element of the same index
  867. j--;
  868. }
  869. } else {
  870. log.log([null, 'Event', eventName, 'Condition is still not met. ' +
  871. 'Holding event from being fired']);
  872. }
  873. }
  874. }
  875.  
  876. log.log([null, 'Event', eventName, 'Event is triggered']);
  877. };
  878.  
  879.  
  880.  
  881. /**
  882. * Function that checks if the current state condition is met before subscribing
  883. * event handler to wait for condition to be fulfilled.
  884. * @method _condition
  885. * @private
  886. * @for Skylink
  887. * @since 0.5.5
  888. */
  889. Skylink.prototype._condition = function(eventName, callback, checkFirst, condition, fireAlways) {
  890. if (typeof condition === 'boolean') {
  891. fireAlways = condition;
  892. condition = null;
  893. }
  894. if (typeof callback === 'function' && typeof checkFirst === 'function') {
  895. if (checkFirst()) {
  896. log.log([null, 'Event', eventName, 'First condition is met. Firing callback']);
  897. callback();
  898. return;
  899. }
  900. log.log([null, 'Event', eventName, 'First condition is not met. Subscribing to event']);
  901. this.once(eventName, callback, condition, fireAlways);
  902. } else {
  903. log.error([null, 'Event', eventName, 'Provided callback or checkFirst is not a function']);
  904. }
  905. };
  906.  
  907. /**
  908. * Function that starts an interval check to wait for a condition to be resolved.
  909. * @method _wait
  910. * @private
  911. * @for Skylink
  912. * @since 0.5.5
  913. */
  914. Skylink.prototype._wait = function(callback, condition, intervalTime, fireAlways) {
  915. fireAlways = (typeof fireAlways === 'undefined' ? false : fireAlways);
  916. if (typeof callback === 'function' && typeof condition === 'function') {
  917. if (condition()) {
  918. log.log([null, 'Event', null, 'Condition is met. Firing callback']);
  919. callback();
  920. return;
  921. }
  922. log.log([null, 'Event', null, 'Condition is not met. Doing a check.']);
  923.  
  924. intervalTime = (typeof intervalTime === 'number') ? intervalTime : 50;
  925.  
  926. var doWait = setInterval(function () {
  927. if (condition()) {
  928. log.log([null, 'Event', null, 'Condition is met after waiting. Firing callback']);
  929. if (!fireAlways){
  930. clearInterval(doWait);
  931. }
  932. callback();
  933. }
  934. }, intervalTime);
  935. } else {
  936. if (typeof callback !== 'function'){
  937. log.error([null, 'Event', null, 'Provided callback is not a function']);
  938. }
  939. if (typeof condition !== 'function'){
  940. log.error([null, 'Event', null, 'Provided condition is not a function']);
  941. }
  942. }
  943. };
  944.  
  945. /**
  946. * Function that throttles a method function to prevent multiple invokes over a specified amount of time.
  947. * Returns a function to be invoked <code>._throttle(fn, 1000)()</code> to make throttling functionality work.
  948. * @method _throttle
  949. * @private
  950. * @for Skylink
  951. * @since 0.5.8
  952. */
  953. Skylink.prototype._throttle = function(func, wait){
  954. var self = this;
  955. return function () {
  956. if (!self._timestamp.func){
  957. //First time run, need to force timestamp to skip condition
  958. self._timestamp.func = self._timestamp.now - wait;
  959. }
  960. var now = Date.now();
  961. if (now - self._timestamp.func < wait) {
  962. return;
  963. }
  964. func.apply(self, arguments);
  965. self._timestamp.func = now;
  966. };
  967. };