1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * Class handling reconnecting the session when it is disconnected due to
10 * The SmartReconnector listens for changes in connection state of
11 * |clientSession| to determine if a reconnection is needed. It then calls into
12 * |connector| to reconnect the session.
17 /** @suppress {duplicate} */
18 var remoting = remoting || {};
22 * @param {remoting.SessionConnector} connector This is used to reconnect the
23 * the session when necessary
24 * @param {remoting.ClientSession} clientSession This represents the current
25 * remote desktop connection. It is used to monitor the changes in
27 * @implements {base.Disposable}
29 remoting.SmartReconnector = function(connector, clientSession) {
31 this.connector_ = connector;
34 this.clientSession_ = clientSession;
37 this.reconnectTimerId_ = null;
40 this.connectionTimeoutTimerId_ = null;
44 reconnect: this.reconnect_.bind(this),
45 reconnectAsync: this.reconnectAsync_.bind(this),
46 startReconnectTimeout: this.startReconnectTimeout_.bind(this),
47 stateChanged: this.stateChanged_.bind(this),
48 videoChannelStateChanged: this.videoChannelStateChanged_.bind(this)
51 clientSession.addEventListener(
52 remoting.ClientSession.Events.stateChanged,
53 this.bound_.stateChanged);
54 clientSession.addEventListener(
55 remoting.ClientSession.Events.videoChannelStateChanged,
56 this.bound_.videoChannelStateChanged);
59 // The online event only means the network adapter is enabled, but
60 // it doesn't necessarily mean that we have a working internet connection.
61 // Therefore, delay the connection by |kReconnectDelay| to allow for the network
63 remoting.SmartReconnector.kReconnectDelay = 2000;
65 // If no frames are received from the server for more than |kConnectionTimeout|,
66 // disconnect the session.
67 remoting.SmartReconnector.kConnectionTimeout = 10000;
69 remoting.SmartReconnector.prototype = {
70 reconnect_: function() {
71 this.cancelPending_();
72 remoting.disconnect();
73 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
74 this.connector_.reconnect();
77 reconnectAsync_: function() {
78 this.cancelPending_();
79 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
80 this.reconnectTimerId_ = window.setTimeout(
81 this.bound_.reconnect, remoting.SmartReconnector.kReconnectDelay);
85 * @param {remoting.ClientSession.StateEvent} event
87 stateChanged_: function(event) {
88 var State = remoting.ClientSession.State;
89 if (event.previous === State.CONNECTED && event.current === State.FAILED) {
90 this.cancelPending_();
91 if (navigator.onLine) {
94 window.addEventListener('online', this.bound_.reconnectAsync, false);
100 * @param {boolean} active This function is called if no frames are received
101 * on the client for more than 1 second.
103 videoChannelStateChanged_: function (active) {
104 this.cancelPending_();
106 // If the channel becomes inactive due to a lack of network connection,
107 // wait for it to go online. The plugin will try to reconnect the video
108 // channel once it is online. If the video channels doesn't finish
109 // reconnecting within the timeout, tear down the session and reconnect.
110 if (navigator.onLine) {
113 window.addEventListener(
114 'online', this.bound_.startReconnectTimeout, false);
119 startReconnectTimeout_: function () {
120 this.cancelPending_();
121 this.connectionTimeoutTimerId_ = window.setTimeout(
122 this.bound_.reconnect, remoting.SmartReconnector.kConnectionTimeout);
125 cancelPending_: function() {
126 window.removeEventListener(
127 'online', this.bound_.startReconnectTimeout, false);
128 window.removeEventListener('online', this.bound_.reconnectAsync, false);
129 window.clearTimeout(this.reconnectTimerId_);
130 window.clearTimeout(this.connectionTimeoutTimerId_);
131 this.reconnectTimerId_ = null;
132 this.connectionTimeoutTimerId_ = null;
135 dispose: function() {
136 this.clientSession_.removeEventListener(
137 remoting.ClientSession.Events.stateChanged,
138 this.bound_.stateChanged);
139 this.clientSession_.removeEventListener(
140 remoting.ClientSession.Events.videoChannelStateChanged,
141 this.bound_.videoChannelStateChanged);