You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

actions.any.ts 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import _ from 'lodash';
  2. import { IReduxState } from '../../app/types';
  3. import {
  4. appendURLParam,
  5. getBackendSafeRoomName,
  6. parseURIString
  7. } from '../util/uri';
  8. import {
  9. CONNECTION_DISCONNECTED,
  10. CONNECTION_ESTABLISHED,
  11. CONNECTION_FAILED,
  12. SET_LOCATION_URL
  13. } from './actionTypes';
  14. import logger from './logger';
  15. /**
  16. * The error structure passed to the {@link connectionFailed} action.
  17. *
  18. * Note there was an intention to make the error resemble an Error instance (to
  19. * the extent that jitsi-meet needs it).
  20. */
  21. export type ConnectionFailedError = {
  22. /**
  23. * The invalid credentials that were used to authenticate and the
  24. * authentication failed.
  25. */
  26. credentials?: {
  27. /**
  28. * The XMPP user's ID.
  29. */
  30. jid: string;
  31. /**
  32. * The XMPP user's password.
  33. */
  34. password: string;
  35. };
  36. /**
  37. * The details about the connection failed event.
  38. */
  39. details?: Object;
  40. /**
  41. * Error message.
  42. */
  43. message?: string;
  44. /**
  45. * One of {@link JitsiConnectionError} constants (defined in
  46. * lib-jitsi-meet).
  47. */
  48. name: string;
  49. /**
  50. * Indicates whether this event is recoverable or not.
  51. */
  52. recoverable?: boolean;
  53. };
  54. /**
  55. * Create an action for when the signaling connection has been lost.
  56. *
  57. * @param {JitsiConnection} connection - The {@code JitsiConnection} which
  58. * disconnected.
  59. * @private
  60. * @returns {{
  61. * type: CONNECTION_DISCONNECTED,
  62. * connection: JitsiConnection
  63. * }}
  64. */
  65. export function connectionDisconnected(connection: Object) {
  66. return {
  67. type: CONNECTION_DISCONNECTED,
  68. connection
  69. };
  70. }
  71. /**
  72. * Create an action for when the signaling connection has been established.
  73. *
  74. * @param {JitsiConnection} connection - The {@code JitsiConnection} which was
  75. * established.
  76. * @param {number} timeEstablished - The time at which the
  77. * {@code JitsiConnection} which was established.
  78. * @public
  79. * @returns {{
  80. * type: CONNECTION_ESTABLISHED,
  81. * connection: JitsiConnection,
  82. * timeEstablished: number
  83. * }}
  84. */
  85. export function connectionEstablished(
  86. connection: Object, timeEstablished: number) {
  87. return {
  88. type: CONNECTION_ESTABLISHED,
  89. connection,
  90. timeEstablished
  91. };
  92. }
  93. /**
  94. * Create an action for when the signaling connection could not be created.
  95. *
  96. * @param {JitsiConnection} connection - The {@code JitsiConnection} which
  97. * failed.
  98. * @param {ConnectionFailedError} error - Error.
  99. * @public
  100. * @returns {{
  101. * type: CONNECTION_FAILED,
  102. * connection: JitsiConnection,
  103. * error: ConnectionFailedError
  104. * }}
  105. */
  106. export function connectionFailed(
  107. connection: Object,
  108. error: ConnectionFailedError) {
  109. const { credentials } = error;
  110. if (credentials && !Object.keys(credentials).length) {
  111. error.credentials = undefined;
  112. }
  113. return {
  114. type: CONNECTION_FAILED,
  115. connection,
  116. error
  117. };
  118. }
  119. /**
  120. * Constructs options to be passed to the constructor of {@code JitsiConnection}
  121. * based on the redux state.
  122. *
  123. * @param {Object} state - The redux state.
  124. * @returns {Object} The options to be passed to the constructor of
  125. * {@code JitsiConnection}.
  126. */
  127. export function constructOptions(state: IReduxState) {
  128. // Deep clone the options to make sure we don't modify the object in the
  129. // redux store.
  130. const options = _.cloneDeep(state['features/base/config']);
  131. let { bosh, websocket } = options;
  132. // TESTING: Only enable WebSocket for some percentage of users.
  133. if (websocket && navigator.product === 'ReactNative') {
  134. if ((Math.random() * 100) >= (options?.testing?.mobileXmppWsThreshold ?? 0)) {
  135. websocket = undefined;
  136. }
  137. }
  138. // Normalize the BOSH URL.
  139. if (bosh && !websocket) {
  140. const { locationURL } = state['features/base/connection'];
  141. if (bosh.startsWith('//')) {
  142. // By default our config.js doesn't include the protocol.
  143. bosh = `${locationURL?.protocol}${bosh}`;
  144. } else if (bosh.startsWith('/')) {
  145. // Handle relative URLs, which won't work on mobile.
  146. const {
  147. protocol,
  148. host,
  149. contextRoot
  150. } = parseURIString(locationURL?.href);
  151. bosh = `${protocol}//${host}${contextRoot || '/'}${bosh.substr(1)}`;
  152. }
  153. }
  154. // WebSocket is preferred over BOSH.
  155. const serviceUrl = websocket || bosh;
  156. logger.log(`Using service URL ${serviceUrl}`);
  157. // Append room to the URL's search.
  158. const { room } = state['features/base/conference'];
  159. if (serviceUrl && room) {
  160. const roomName = getBackendSafeRoomName(room);
  161. options.serviceUrl = appendURLParam(serviceUrl, 'room', roomName ?? '');
  162. if (options.websocketKeepAliveUrl) {
  163. options.websocketKeepAliveUrl = appendURLParam(options.websocketKeepAliveUrl, 'room', roomName ?? '');
  164. }
  165. }
  166. return options;
  167. }
  168. /**
  169. * Sets the location URL of the application, connection, conference, etc.
  170. *
  171. * @param {URL} [locationURL] - The location URL of the application,
  172. * connection, conference, etc.
  173. * @returns {{
  174. * type: SET_LOCATION_URL,
  175. * locationURL: URL
  176. * }}
  177. */
  178. export function setLocationURL(locationURL?: URL) {
  179. return {
  180. type: SET_LOCATION_URL,
  181. locationURL
  182. };
  183. }