diff --git a/bigbluebutton-client/resources/prod/lib/kurento-extension.js b/bigbluebutton-client/resources/prod/lib/kurento-extension.js
index b7aafb39360ca65500dcb67a4b6d9f4eabda5b34..ad7f6cdff2d5cd768f64f2ee5ede6bf4b98a6fdc 100644
--- a/bigbluebutton-client/resources/prod/lib/kurento-extension.js
+++ b/bigbluebutton-client/resources/prod/lib/kurento-extension.js
@@ -9,6 +9,7 @@ const SFU_APP = "screenshare";
 const ON_ICE_CANDIDATE_MSG = "onIceCandidate";
 const START_MSG = "start";
 const START_RESPONSE_MSG = "startResponse";
+const PING_INTERVAL = 15000;
 
 Kurento = function (
   tag,
@@ -44,6 +45,7 @@ Kurento = function (
   this.kurentoPort = 'bbb-webrtc-sfu';
   this.hostName = window.location.hostname;
   this.socketUrl = `wss://${this.hostName}/${this.kurentoPort}`;
+  this.pingInterval = null;
 
   this.iceServers = null;
 
@@ -60,6 +62,7 @@ Kurento = function (
       _this.logError('Default error handler');
     };
   }
+
 };
 
 this.KurentoManager = function () {
@@ -75,11 +78,11 @@ KurentoManager.prototype.exitScreenShare = function () {
       this.kurentoScreenshare.ws.close();
     }
 
-    this.kurentoScreenshare.disposeScreenShare();
-    this.kurentoScreenshare = null;
-  }
+    if (this.kurentoScreenshare.pingInterval) {
+      clearInterval(this.kurentoScreenshare.pingInterval);
+    }
 
-  if (this.kurentoScreenshare) {
+    this.kurentoScreenshare.disposeScreenShare();
     this.kurentoScreenshare = null;
   }
 
@@ -96,11 +99,11 @@ KurentoManager.prototype.exitVideo = function () {
       this.kurentoVideo.ws.close();
     }
 
-    this.kurentoVideo.disposeScreenShare();
-    this.kurentoVideo = null;
-  }
+    if (this.kurentoVideo.pingInterval) {
+      clearInterval(this.kurentoVideo.pingInterval);
+    }
 
-  if (this.kurentoVideo) {
+    this.kurentoVideo.disposeScreenShare();
     this.kurentoVideo = null;
   }
 };
@@ -149,6 +152,7 @@ Kurento.prototype.init = function () {
       self.onFail('Websocket connection error');
     };
     this.ws.onopen = function () {
+      self.pingInterval = setInterval(self.ping.bind(self), PING_INTERVAL);
       self.mediaCallback();
     };
   } else { console.log('this browser does not support websockets'); }
@@ -166,6 +170,8 @@ Kurento.prototype.onWSMessage = function (message) {
     case 'iceCandidate':
       this.webRtcPeer.addIceCandidate(parsedMessage.candidate);
       break;
+    case 'pong':
+      break;
     default:
       console.error('Unrecognized message', parsedMessage);
   }
@@ -364,6 +370,13 @@ Kurento.prototype.disposeScreenShare = function () {
   }
 };
 
+Kurento.prototype.ping = function () {
+  const message = {
+    id: 'ping'
+  };
+  this.sendMessage(message);
+}
+
 Kurento.prototype.sendMessage = function (message) {
   const jsonMessage = JSON.stringify(message);
   console.log(`Sending message: ${jsonMessage}`);
diff --git a/bigbluebutton-html5/client/compatibility/kurento-extension.js b/bigbluebutton-html5/client/compatibility/kurento-extension.js
index f376a9c19da82902eea1800c0b2d9f973365965f..ad7f6cdff2d5cd768f64f2ee5ede6bf4b98a6fdc 100644
--- a/bigbluebutton-html5/client/compatibility/kurento-extension.js
+++ b/bigbluebutton-html5/client/compatibility/kurento-extension.js
@@ -9,6 +9,7 @@ const SFU_APP = "screenshare";
 const ON_ICE_CANDIDATE_MSG = "onIceCandidate";
 const START_MSG = "start";
 const START_RESPONSE_MSG = "startResponse";
+const PING_INTERVAL = 15000;
 
 Kurento = function (
   tag,
@@ -44,6 +45,7 @@ Kurento = function (
   this.kurentoPort = 'bbb-webrtc-sfu';
   this.hostName = window.location.hostname;
   this.socketUrl = `wss://${this.hostName}/${this.kurentoPort}`;
+  this.pingInterval = null;
 
   this.iceServers = null;
 
@@ -60,6 +62,7 @@ Kurento = function (
       _this.logError('Default error handler');
     };
   }
+
 };
 
 this.KurentoManager = function () {
@@ -75,11 +78,11 @@ KurentoManager.prototype.exitScreenShare = function () {
       this.kurentoScreenshare.ws.close();
     }
 
-    this.kurentoScreenshare.disposeScreenShare();
-    this.kurentoScreenshare = null;
-  }
+    if (this.kurentoScreenshare.pingInterval) {
+      clearInterval(this.kurentoScreenshare.pingInterval);
+    }
 
-  if (this.kurentoScreenshare) {
+    this.kurentoScreenshare.disposeScreenShare();
     this.kurentoScreenshare = null;
   }
 
@@ -96,11 +99,11 @@ KurentoManager.prototype.exitVideo = function () {
       this.kurentoVideo.ws.close();
     }
 
-    this.kurentoVideo.disposeScreenShare();
-    this.kurentoVideo = null;
-  }
+    if (this.kurentoVideo.pingInterval) {
+      clearInterval(this.kurentoVideo.pingInterval);
+    }
 
-  if (this.kurentoVideo) {
+    this.kurentoVideo.disposeScreenShare();
     this.kurentoVideo = null;
   }
 };
@@ -149,6 +152,7 @@ Kurento.prototype.init = function () {
       self.onFail('Websocket connection error');
     };
     this.ws.onopen = function () {
+      self.pingInterval = setInterval(self.ping.bind(self), PING_INTERVAL);
       self.mediaCallback();
     };
   } else { console.log('this browser does not support websockets'); }
@@ -166,6 +170,8 @@ Kurento.prototype.onWSMessage = function (message) {
     case 'iceCandidate':
       this.webRtcPeer.addIceCandidate(parsedMessage.candidate);
       break;
+    case 'pong':
+      break;
     default:
       console.error('Unrecognized message', parsedMessage);
   }
@@ -364,6 +370,13 @@ Kurento.prototype.disposeScreenShare = function () {
   }
 };
 
+Kurento.prototype.ping = function () {
+  const message = {
+    id: 'ping'
+  };
+  this.sendMessage(message);
+}
+
 Kurento.prototype.sendMessage = function (message) {
   const jsonMessage = JSON.stringify(message);
   console.log(`Sending message: ${jsonMessage}`);
@@ -488,3 +501,41 @@ window.getChromeScreenConstraints = function (callback, extensionId) {
     },
   );
 };
+
+// a function to check whether the browser (Chrome only) is in an isIncognito
+// session. Requires 1 mandatory callback that only gets called if the browser
+// session is incognito. The callback for not being incognito is optional.
+// Attempts to retrieve the chrome filesystem API.
+window.checkIfIncognito = function(isIncognito, isNotIncognito = function () {}) {
+  isIncognito = Kurento.normalizeCallback(isIncognito);
+  isNotIncognito = Kurento.normalizeCallback(isNotIncognito);
+
+  var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
+  if (!fs) {
+    isNotIncognito();
+    return;
+  }
+  fs(window.TEMPORARY, 100, function(){isNotIncognito()}, function(){isIncognito()});
+};
+
+window.checkChromeExtInstalled = function (callback, chromeExtensionId) {
+  callback = Kurento.normalizeCallback(callback);
+
+  if (typeof chrome === "undefined" || !chrome || !chrome.runtime) {
+    // No API, so no extension for sure
+    callback(false);
+    return;
+  }
+  chrome.runtime.sendMessage(
+    chromeExtensionId,
+    { getVersion: true },
+    function (response) {
+      if (!response || !response.version) {
+        // Communication failure - assume that no endpoint exists
+        callback(false);
+        return;
+      }
+      callback(true);
+    }
+  );
+}
diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx b/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx
index 48732d7c67bcca5a5df951c0dd0e188134f5e011..dddf331f326cc247077cd1d5104fd1f0273d9837 100755
--- a/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx
@@ -33,8 +33,8 @@ const intlMessages = defineMessages({
   },
 });
 
-const RECONNECT_WAIT_TIME = 5000;
 const CAMERA_SHARE_FAILED_WAIT_TIME = 10000;
+const PING_INTERVAL = 15000;
 
 class VideoProvider extends Component {
   constructor(props) {
@@ -128,6 +128,8 @@ class VideoProvider extends Component {
       this.sendMessage(this.wsQueue.pop());
     }
 
+    this.pingInterval = setInterval(this.ping.bind(this), PING_INTERVAL);
+
     this.setState({ socketOpen: true });
   }
 
@@ -135,10 +137,18 @@ class VideoProvider extends Component {
     log('debug', '------ Websocket connection closed.');
 
     this.stopWebRTCPeer(this.props.userId);
+    clearInterval(this.pingInterval);
 
     this.setState({ socketOpen: false });
   }
 
+  ping() {
+    const message = {
+      id: 'ping'
+    };
+    this.sendMessage(message);
+  }
+
   disconnected(id) {
     this.reconnectList.push(id);
 
@@ -169,6 +179,10 @@ class VideoProvider extends Component {
         this.handleIceCandidate(parsedMessage);
         break;
 
+      case 'pong':
+        console.debug("Received pong from server");
+        break;
+
       case 'error':
       default:
         this.handleError(parsedMessage);
diff --git a/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js b/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js
index 0dc0a6d37cd5ac920fa053967a161b3bd1dfe419..22df53957ad6fc278641c08b9d14b702750c098a 100644
--- a/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js
+++ b/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js
@@ -50,6 +50,12 @@ module.exports = class WebsocketConnectionManager {
 
         try {
           message = JSON.parse(data);
+
+          if (message.id === 'ping') {
+            ws.sendMessage({id: 'pong'});
+            return;
+          }
+
           message.connectionId = ws.id;
 
           if (!ws.sessionId) {
diff --git a/labs/bbb-webrtc-sfu/package-lock.json b/labs/bbb-webrtc-sfu/package-lock.json
index c2cab4e85ec27fd894aa519fc30604b52e6da702..2230bf4bcbc75ad0e3e4c14e8fdee218a4c832c4 100644
--- a/labs/bbb-webrtc-sfu/package-lock.json
+++ b/labs/bbb-webrtc-sfu/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "bbb-webrtc-sfu",
-  "version": "0.0.3",
+  "version": "0.0.5",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -171,39 +171,26 @@
         "promise": "7.1.1",
         "promisecallback": "0.0.4",
         "reconnect-ws": "github:KurentoForks/reconnect-ws#f287385d75861654528c352e60221f95c9209f8a"
+      }
+    },
+    "kurento-client-core": {
+      "version": "github:Kurento/kurento-client-core-js#2160f8e6938f138b52b72a5c5c354d1e5fce1ca0"
+    },
+    "kurento-client-elements": {
+      "version": "github:Kurento/kurento-client-elements-js#cbd1ff67fbf0faddc9f6f266bb33e449bc9e1f81"
+    },
+    "kurento-client-filters": {
+      "version": "github:Kurento/kurento-client-filters-js#51308da53e432a2db9559dcdb308d87951417bf0"
+    },
+    "kurento-jsonrpc": {
+      "version": "github:Kurento/kurento-jsonrpc-js#827827bbeb557e1c1901f5a562c4c700b9a51401",
+      "requires": {
+        "bufferutil": "1.2.1",
+        "inherits": "2.0.3",
+        "utf-8-validate": "1.2.2",
+        "ws": "1.1.5"
       },
       "dependencies": {
-        "kurento-client-core": {
-          "version": "github:Kurento/kurento-client-core-js#2160f8e6938f138b52b72a5c5c354d1e5fce1ca0"
-        },
-        "kurento-client-elements": {
-          "version": "github:Kurento/kurento-client-elements-js#cbd1ff67fbf0faddc9f6f266bb33e449bc9e1f81"
-        },
-        "kurento-client-filters": {
-          "version": "github:Kurento/kurento-client-filters-js#51308da53e432a2db9559dcdb308d87951417bf0"
-        },
-        "kurento-jsonrpc": {
-          "version": "github:Kurento/kurento-jsonrpc-js#827827bbeb557e1c1901f5a562c4c700b9a51401",
-          "requires": {
-            "bufferutil": "1.2.1",
-            "inherits": "2.0.3",
-            "utf-8-validate": "1.2.2",
-            "ws": "1.1.5"
-          }
-        },
-        "reconnect-core": {
-          "version": "github:KurentoForks/reconnect-core#921d43e91578abb2fb2613f585c010c1939cf734",
-          "requires": {
-            "backoff": "2.3.0"
-          }
-        },
-        "reconnect-ws": {
-          "version": "github:KurentoForks/reconnect-ws#f287385d75861654528c352e60221f95c9209f8a",
-          "requires": {
-            "reconnect-core": "github:KurentoForks/reconnect-core#921d43e91578abb2fb2613f585c010c1939cf734",
-            "websocket-stream": "0.5.1"
-          }
-        },
         "ws": {
           "version": "1.1.5",
           "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
@@ -291,6 +278,19 @@
         "nanoid": "1.0.1"
       }
     },
+    "reconnect-core": {
+      "version": "github:KurentoForks/reconnect-core#921d43e91578abb2fb2613f585c010c1939cf734",
+      "requires": {
+        "backoff": "2.3.0"
+      }
+    },
+    "reconnect-ws": {
+      "version": "github:KurentoForks/reconnect-ws#f287385d75861654528c352e60221f95c9209f8a",
+      "requires": {
+        "reconnect-core": "github:KurentoForks/reconnect-core#921d43e91578abb2fb2613f585c010c1939cf734",
+        "websocket-stream": "0.5.1"
+      }
+    },
     "redis": {
       "version": "2.8.0",
       "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz",
diff --git a/labs/bbb-webrtc-sfu/package.json b/labs/bbb-webrtc-sfu/package.json
index 0c380aa82af781c39a673d8359b2350fd78b5206..10a253b70b088c642fc94701d52a46129572e661 100644
--- a/labs/bbb-webrtc-sfu/package.json
+++ b/labs/bbb-webrtc-sfu/package.json
@@ -1,6 +1,6 @@
 {
   "name": "bbb-webrtc-sfu",
-  "version": "0.0.3",
+  "version": "0.0.5",
   "private": true,
   "scripts": {
     "start": "node server.js"