modified lib-jitsi-meet dev repo
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.

strophe.ping.js 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* global $, $iq, Strophe */
  2. import { getLogger } from "jitsi-meet-logger";
  3. const logger = getLogger(__filename);
  4. import ConnectionPlugin from "./ConnectionPlugin";
  5. import GlobalOnErrorHandler from "../util/GlobalOnErrorHandler";
  6. /**
  7. * Ping every 10 sec
  8. */
  9. const PING_INTERVAL = 10000;
  10. /**
  11. * Ping timeout error after 15 sec of waiting.
  12. */
  13. const PING_TIMEOUT = 15000;
  14. /**
  15. * Will close the connection after 3 consecutive ping errors.
  16. */
  17. const PING_THRESHOLD = 3;
  18. /**
  19. * XEP-0199 ping plugin.
  20. *
  21. * Registers "urn:xmpp:ping" namespace under Strophe.NS.PING.
  22. */
  23. class PingConnectionPlugin extends ConnectionPlugin {
  24. constructor() {
  25. super();
  26. this.failedPings = 0;
  27. }
  28. /**
  29. * Initializes the plugin. Method called by Strophe.
  30. * @param connection Strophe connection instance.
  31. */
  32. init (connection) {
  33. super.init(connection);
  34. Strophe.addNamespace('PING', "urn:xmpp:ping");
  35. }
  36. /**
  37. * Sends "ping" to given <tt>jid</tt>
  38. * @param jid the JID to which ping request will be sent.
  39. * @param success callback called on success.
  40. * @param error callback called on error.
  41. * @param timeout ms how long are we going to wait for the response. On
  42. * timeout <tt>error<//t> callback is called with undefined error
  43. * argument.
  44. */
  45. ping (jid, success, error, timeout) {
  46. const iq = $iq({type: 'get', to: jid});
  47. iq.c('ping', {xmlns: Strophe.NS.PING});
  48. this.connection.sendIQ(iq, success, error, timeout);
  49. }
  50. /**
  51. * Checks if given <tt>jid</tt> has XEP-0199 ping support.
  52. * @param jid the JID to be checked for ping support.
  53. * @param callback function with boolean argument which will be
  54. * <tt>true</tt> if XEP-0199 ping is supported by given <tt>jid</tt>
  55. */
  56. hasPingSupport (jid, callback) {
  57. const disco = this.connection.disco;
  58. // XXX The following disco.info was observed to throw a "TypeError:
  59. // Cannot read property 'info' of undefined" during porting to React
  60. // Native. Since disco is checked in multiple places (e.g.
  61. // strophe.jingle.js, strophe.rayo.js), check it here as well.
  62. if (disco) {
  63. disco.info(jid, null, (result) => {
  64. const ping
  65. = $(result).find('>>feature[var="urn:xmpp:ping"]');
  66. callback(ping.length > 0);
  67. }, (error) => {
  68. const errmsg = "Ping feature discovery error";
  69. GlobalOnErrorHandler.callErrorHandler(new Error(
  70. errmsg + ": " + error));
  71. logger.error(errmsg, error);
  72. callback(false);
  73. });
  74. } else {
  75. // FIXME Should callback be invoked here? Maybe with false as an
  76. // argument?
  77. }
  78. }
  79. /**
  80. * Starts to send ping in given interval to specified remote JID.
  81. * This plugin supports only one such task and <tt>stopInterval</tt>
  82. * must be called before starting a new one.
  83. * @param remoteJid remote JID to which ping requests will be sent to.
  84. * @param interval task interval in ms.
  85. */
  86. startInterval (remoteJid, interval = PING_INTERVAL) {
  87. if (this.intervalId) {
  88. const errmsg = "Ping task scheduled already";
  89. GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));
  90. logger.error(errmsg);
  91. return;
  92. }
  93. this.intervalId = window.setInterval(() => {
  94. this.ping(remoteJid, () => {
  95. this.failedPings = 0;
  96. }, (error) => {
  97. this.failedPings += 1;
  98. const errmsg = "Ping " + (error ? "error" : "timeout");
  99. if (this.failedPings >= PING_THRESHOLD) {
  100. GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));
  101. logger.error(errmsg, error);
  102. // FIXME it doesn't help to disconnect when 3rd PING
  103. // times out, it only stops Strophe from retrying.
  104. // Not really sure what's the right thing to do in that
  105. // situation, but just closing the connection makes no
  106. // sense.
  107. //self.connection.disconnect();
  108. } else {
  109. logger.warn(errmsg, error);
  110. }
  111. }, PING_TIMEOUT);
  112. }, interval);
  113. logger.info("XMPP pings will be sent every " + interval + " ms");
  114. }
  115. /**
  116. * Stops current "ping" interval task.
  117. */
  118. stopInterval () {
  119. if (this.intervalId) {
  120. window.clearInterval(this.intervalId);
  121. this.intervalId = null;
  122. this.failedPings = 0;
  123. logger.info("Ping interval cleared");
  124. }
  125. }
  126. }
  127. export default function () {
  128. Strophe.addConnectionPlugin('ping', new PingConnectionPlugin());
  129. }