Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

statsEmitter.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // @flow
  2. import _ from 'lodash';
  3. import {
  4. JitsiConnectionQualityEvents,
  5. JitsiE2ePingEvents
  6. } from '../base/lib-jitsi-meet';
  7. declare var APP: Object;
  8. /**
  9. * Contains all the callbacks to be notified when stats are updated.
  10. *
  11. * {
  12. * userId: Function[]
  13. * }
  14. */
  15. const subscribers = {};
  16. /**
  17. * A singleton that acts as a pub/sub service for connection stat updates.
  18. */
  19. const statsEmitter = {
  20. /**
  21. * Have {@code statsEmitter} subscribe to stat updates from a given
  22. * conference.
  23. *
  24. * @param {JitsiConference} conference - The conference for which
  25. * {@code statsEmitter} should subscribe for stat updates.
  26. * @returns {void}
  27. */
  28. startListeningForStats(conference: Object) {
  29. conference.on(JitsiConnectionQualityEvents.LOCAL_STATS_UPDATED,
  30. stats => this._onStatsUpdated(conference.myUserId(), stats));
  31. conference.on(JitsiConnectionQualityEvents.REMOTE_STATS_UPDATED,
  32. (id, stats) => this._emitStatsUpdate(id, stats));
  33. conference.on(
  34. JitsiE2ePingEvents.E2E_RTT_CHANGED,
  35. (participant, e2eRtt) => {
  36. const stats = {
  37. e2eRtt,
  38. region: participant.getProperty('region')
  39. };
  40. this._emitStatsUpdate(participant.getId(), stats);
  41. });
  42. },
  43. /**
  44. * Add a subscriber to be notified when stats are updated for a specified
  45. * user id.
  46. *
  47. * @param {string} id - The user id whose stats updates are of interest.
  48. * @param {Function} callback - The function to invoke when stats for the
  49. * user have been updated.
  50. * @returns {void}
  51. */
  52. subscribeToClientStats(id: ?string, callback: Function) {
  53. if (!id) {
  54. return;
  55. }
  56. if (!subscribers[id]) {
  57. subscribers[id] = [];
  58. }
  59. subscribers[id].push(callback);
  60. },
  61. /**
  62. * Remove a subscriber that is listening for stats updates for a specified
  63. * user id.
  64. *
  65. * @param {string} id - The user id whose stats updates are no longer of
  66. * interest.
  67. * @param {Function} callback - The function that is currently subscribed to
  68. * stat updates for the specified user id.
  69. * @returns {void}
  70. */
  71. unsubscribeToClientStats(id: string, callback: Function) {
  72. if (!subscribers[id]) {
  73. return;
  74. }
  75. const filteredSubscribers = subscribers[id].filter(
  76. subscriber => subscriber !== callback);
  77. if (filteredSubscribers.length) {
  78. subscribers[id] = filteredSubscribers;
  79. } else {
  80. delete subscribers[id];
  81. }
  82. },
  83. /**
  84. * Emit a stat update to all those listening for a specific user's
  85. * connection stats.
  86. *
  87. * @param {string} id - The user id the stats are associated with.
  88. * @param {Object} stats - New connection stats for the user.
  89. * @returns {void}
  90. */
  91. _emitStatsUpdate(id: string, stats: Object = {}) {
  92. const callbacks = subscribers[id] || [];
  93. callbacks.forEach(callback => {
  94. callback(stats);
  95. });
  96. },
  97. /**
  98. * Emit a stat update to all those listening for local stat updates. Will
  99. * also update listeners of remote user stats of changes related to their
  100. * stats.
  101. *
  102. * @param {string} currentUserId - The user id for the local user.
  103. * @param {Object} stats - Connection stats for the local user as provided
  104. * by the library.
  105. * @returns {void}
  106. */
  107. _onStatsUpdated(currentUserId: string, stats: Object) {
  108. const allUserFramerates = stats.framerate || {};
  109. const allUserResolutions = stats.resolution || {};
  110. // FIXME resolution and framerate are hashes keyed off of user ids with
  111. // stat values. Receivers of stats expect resolution and framerate to
  112. // be primatives, not hashes, so overwrites the 'lib-jitsi-meet' stats
  113. // objects.
  114. const modifiedLocalStats = Object.assign({}, stats, {
  115. framerate: allUserFramerates[currentUserId],
  116. resolution: allUserResolutions[currentUserId]
  117. });
  118. this._emitStatsUpdate(currentUserId, modifiedLocalStats);
  119. // Get all the unique user ids from the framerate and resolution stats
  120. // and update remote user stats as needed.
  121. const framerateUserIds = Object.keys(allUserFramerates);
  122. const resolutionUserIds = Object.keys(allUserResolutions);
  123. _.union(framerateUserIds, resolutionUserIds)
  124. .filter(id => id !== currentUserId)
  125. .forEach(id => {
  126. const remoteUserStats = {};
  127. const framerate = allUserFramerates[id];
  128. if (framerate) {
  129. remoteUserStats.framerate = framerate;
  130. }
  131. const resolution = allUserResolutions[id];
  132. if (resolution) {
  133. remoteUserStats.resolution = resolution;
  134. }
  135. this._emitStatsUpdate(id, remoteUserStats);
  136. });
  137. }
  138. };
  139. export default statsEmitter;