util.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import { BinaryPackChunker } from "./dataconnection/BufferedConnection/binaryPackChunker";
  2. import * as BinaryPack from "peerjs-js-binarypack";
  3. import { Supports } from "./supports";
  4. import { validateId } from "./utils/validateId";
  5. import { randomToken } from "./utils/randomToken";
  6. export interface UtilSupportsObj {
  7. /**
  8. * The current browser.
  9. * This property can be useful in determining whether two peers can connect.
  10. *
  11. * ```ts
  12. * if (util.browser === 'firefox') {
  13. * // OK to peer with Firefox peers.
  14. * }
  15. * ```
  16. *
  17. * `util.browser` can currently have the values
  18. * `'firefox', 'chrome', 'safari', 'edge', 'Not a supported browser.', 'Not a browser.' (unknown WebRTC-compatible agent).
  19. */
  20. browser: boolean;
  21. webRTC: boolean;
  22. /**
  23. * True if the current browser supports media streams and PeerConnection.
  24. */
  25. audioVideo: boolean;
  26. /**
  27. * True if the current browser supports DataChannel and PeerConnection.
  28. */
  29. data: boolean;
  30. binaryBlob: boolean;
  31. /**
  32. * True if the current browser supports reliable DataChannels.
  33. */
  34. reliable: boolean;
  35. }
  36. const DEFAULT_CONFIG = {
  37. iceServers: [
  38. { urls: "stun:stun.l.google.com:19302" },
  39. {
  40. urls: [
  41. "turn:eu-0.turn.peerjs.com:3478",
  42. "turn:us-0.turn.peerjs.com:3478",
  43. ],
  44. username: "peerjs",
  45. credential: "peerjsp",
  46. },
  47. ],
  48. sdpSemantics: "unified-plan",
  49. };
  50. export class Util extends BinaryPackChunker {
  51. noop(): void {}
  52. readonly CLOUD_HOST = "0.peerjs.com";
  53. readonly CLOUD_PORT = 443;
  54. // Browsers that need chunking:
  55. readonly chunkedBrowsers = { Chrome: 1, chrome: 1 };
  56. // Returns browser-agnostic default config
  57. readonly defaultConfig = DEFAULT_CONFIG;
  58. readonly browser = Supports.getBrowser();
  59. readonly browserVersion = Supports.getVersion();
  60. pack = BinaryPack.pack;
  61. unpack = BinaryPack.unpack;
  62. /**
  63. * A hash of WebRTC features mapped to booleans that correspond to whether the feature is supported by the current browser.
  64. *
  65. * :::caution
  66. * Only the properties documented here are guaranteed to be present on `util.supports`
  67. * :::
  68. */
  69. readonly supports = (function () {
  70. const supported: UtilSupportsObj = {
  71. browser: Supports.isBrowserSupported(),
  72. webRTC: Supports.isWebRTCSupported(),
  73. audioVideo: false,
  74. data: false,
  75. binaryBlob: false,
  76. reliable: false,
  77. };
  78. if (!supported.webRTC) return supported;
  79. let pc: RTCPeerConnection;
  80. try {
  81. pc = new RTCPeerConnection(DEFAULT_CONFIG);
  82. supported.audioVideo = true;
  83. let dc: RTCDataChannel;
  84. try {
  85. dc = pc.createDataChannel("_PEERJSTEST", { ordered: true });
  86. supported.data = true;
  87. supported.reliable = !!dc.ordered;
  88. // Binary test
  89. try {
  90. dc.binaryType = "blob";
  91. supported.binaryBlob = !Supports.isIOS;
  92. } catch (e) {}
  93. } catch (e) {
  94. } finally {
  95. if (dc) {
  96. dc.close();
  97. }
  98. }
  99. } catch (e) {
  100. } finally {
  101. if (pc) {
  102. pc.close();
  103. }
  104. }
  105. return supported;
  106. })();
  107. // Ensure alphanumeric ids
  108. validateId = validateId;
  109. randomToken = randomToken;
  110. blobToArrayBuffer(
  111. blob: Blob,
  112. cb: (arg: ArrayBuffer | null) => void,
  113. ): FileReader {
  114. const fr = new FileReader();
  115. fr.onload = function (evt) {
  116. if (evt.target) {
  117. cb(evt.target.result as ArrayBuffer);
  118. }
  119. };
  120. fr.readAsArrayBuffer(blob);
  121. return fr;
  122. }
  123. binaryStringToArrayBuffer(binary: string): ArrayBuffer | SharedArrayBuffer {
  124. const byteArray = new Uint8Array(binary.length);
  125. for (let i = 0; i < binary.length; i++) {
  126. byteArray[i] = binary.charCodeAt(i) & 0xff;
  127. }
  128. return byteArray.buffer;
  129. }
  130. isSecure(): boolean {
  131. return location.protocol === "https:";
  132. }
  133. }
  134. /**
  135. * Provides a variety of helpful utilities.
  136. *
  137. * :::caution
  138. * Only the utilities documented here are guaranteed to be present on `util`.
  139. * Undocumented utilities can be removed without warning.
  140. * We don't consider these to be breaking changes.
  141. * :::
  142. */
  143. export const util = new Util();