2 * Copyright (c) 2010 the original author or authors.
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
19 function bind(org_cometd)
\r
21 if (!org_cometd.COOKIE)
\r
23 org_cometd.COOKIE = {};
\r
24 org_cometd.COOKIE.set = function(name, value, options)
\r
28 org_cometd.COOKIE.get = function(name)
\r
35 * The reload extension allows a page to be loaded (or reloaded)
\r
36 * without having to re-handshake in the new (or reloaded) page,
\r
37 * therefore resuming the existing cometd connection.
\r
39 * When the reload() method is called, the state of the cometd
\r
40 * connection and of the cometd subscriptions is stored in a cookie
\r
41 * with a short max-age.
\r
42 * The reload() method must therefore be called by page unload
\r
43 * handlers, often provided by JavaScript toolkits.
\r
45 * When the page is (re)loaded, this extension checks the cookie
\r
46 * and restores the cometd connection and the cometd subscriptions.
\r
48 return org_cometd.ReloadExtension = function(configuration)
\r
53 var _cookieName = 'org.cometd.reload';
\r
54 var _cookiePath = '/';
\r
55 var _cookieMaxAge = 5;
\r
58 function _reload(config)
\r
60 if (_state && _state.handshakeResponse !== null)
\r
63 _state.cookiePath = _cookiePath;
\r
64 var cookie = org_cometd.JSON.toJSON(_state);
\r
65 _debug('Reload extension saving cookie value', cookie);
\r
66 org_cometd.COOKIE.set(_cookieName, cookie, {
\r
67 'max-age': _cookieMaxAge,
\r
69 expires: new Date(new Date().getTime() + _cookieMaxAge * 1000)
\r
74 function _similarState(oldState)
\r
76 // We want to check here that the CometD object
\r
77 // did not change much between reloads.
\r
78 // We just check the URL for now, but in future
\r
79 // further checks may involve the transport type
\r
80 // and other configuration parameters.
\r
81 return _state.url == oldState.url;
\r
84 function _configure(config)
\r
88 if (typeof config.cookieMaxAge === 'number')
\r
90 _cookieMaxAge = config.cookieMaxAge;
\r
92 if (typeof config.cookieName === 'string')
\r
94 _cookieName = config.cookieName;
\r
96 if (typeof config.cookiePath === 'string')
\r
98 _cookiePath = config.cookiePath;
\r
103 this.configure = _configure;
\r
105 this.registered = function(name, cometd)
\r
108 _cometd.reload = _reload;
\r
109 _debug = _cometd._debug;
\r
112 this.unregistered = function()
\r
114 delete _cometd.reload;
\r
118 this.outgoing = function(message)
\r
120 var channel = message.channel;
\r
122 if (channel == '/meta/handshake')
\r
125 _state.url = _cometd.getURL();
\r
127 var cookie = org_cometd.COOKIE.get(_cookieName);
\r
128 _debug('Reload extension found cookie value', cookie);
\r
129 // Is there a saved handshake response from a prior load ?
\r
134 var oldState = org_cometd.JSON.fromJSON(cookie);
\r
136 // Remove the cookie, not needed anymore
\r
137 org_cometd.COOKIE.set(_cookieName, '', {
\r
139 path: oldState.cookiePath,
\r
143 if (oldState.handshakeResponse && _similarState(oldState))
\r
145 _debug('Reload extension restoring state', oldState);
\r
146 setTimeout(function()
\r
148 _debug('Reload extension replaying handshake response', oldState.handshakeResponse);
\r
149 _state.handshakeResponse = oldState.handshakeResponse;
\r
150 _state.transportType = oldState.transportType;
\r
151 _state.reloading = true;
\r
152 var response = _cometd._mixin(true, {}, _state.handshakeResponse, {ext: {reload: true}});
\r
153 response.supportedConnectionTypes = [_state.transportType];
\r
154 _cometd.receive(response);
\r
155 _debug('Reload extension replayed handshake response', response);
\r
158 // delay any sends until first connect is complete.
\r
162 _cometd.startBatch();
\r
164 // This handshake is aborted, as we will replay the prior handshake response
\r
169 _debug('Reload extension could not restore state', oldState);
\r
174 _debug('Reload extension error while trying to restore cookie', x);
\r
178 else if (channel == '/meta/connect')
\r
180 if (!_state.transportType)
\r
182 _state.transportType = message.connectionType;
\r
183 _debug('Reload extension tracked transport type', _state.transportType);
\r
189 this.incoming = function(message)
\r
191 if (message.successful)
\r
193 switch (message.channel)
\r
195 case '/meta/handshake':
\r
196 // If the handshake response is already present, then we're replaying it.
\r
197 // Since the replay may have modified the handshake response, do not record it here.
\r
198 if (!_state.handshakeResponse)
\r
200 // Save successful handshake response
\r
201 _state.handshakeResponse = message;
\r
202 _debug('Reload extension tracked handshake response', message);
\r
205 case '/meta/disconnect':
\r
208 case '/meta/connect':
\r
211 _cometd.endBatch();
\r
222 _configure(configuration);
\r
226 if (typeof define === 'function' && define.amd)
\r
228 define(['org/cometd'], bind);
\r