Skip to content

Commit

Permalink
Fix for #565 and #523
Browse files Browse the repository at this point in the history
  • Loading branch information
jfarcand committed Feb 5, 2013
1 parent d777694 commit 8a81a48
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.atmosphere.interceptor.DefaultHeadersInterceptor;
import org.atmosphere.interceptor.JSONPAtmosphereInterceptor;
import org.atmosphere.interceptor.JavaScriptProtocol;
import org.atmosphere.interceptor.OnDisconnectInterceptor;
import org.atmosphere.interceptor.SSEAtmosphereInterceptor;
import org.atmosphere.interceptor.StreamingAtmosphereInterceptor;
import org.atmosphere.util.AtmosphereConfigReader;
Expand Down Expand Up @@ -607,6 +608,8 @@ protected void configureAtmosphereInterceptor(ServletConfig sc) {
logger.info("Installing Default AtmosphereInterceptor");
s = sc.getInitParameter(ApplicationConfig.DISABLE_ATMOSPHEREINTERCEPTOR);
if (s == null) {
// OnDisconnect
interceptors.addFirst(newAInterceptor(OnDisconnectInterceptor.class));
// ADD Tracking ID Handshake
interceptors.addFirst(newAInterceptor(JavaScriptProtocol.class));
// ADD JSONP support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public class AtmosphereResourceImpl implements AtmosphereResource {
private boolean resumeOnBroadcast = false;
private Object writeOnTimeout = null;
private boolean disableSuspend = false;
private final AtomicBoolean disconnected = new AtomicBoolean(false);

private final ConcurrentLinkedQueue<AtmosphereResourceEventListener> listeners =
new ConcurrentLinkedQueue<AtmosphereResourceEventListener>();
Expand Down Expand Up @@ -641,7 +642,9 @@ public AtmosphereResource notifyListeners(AtmosphereResourceEvent event) {
Action oldAction = action;
try {
if (event.isCancelled()) {
onDisconnect(event);
if (!disconnected.getAndSet(true)) {
onDisconnect(event);
}
} else if (event.isResuming() || event.isResumedOnTimeout()) {
onResume(event);
} else if (!isSuspendEvent.getAndSet(true) && event.isSuspended()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public interface HeaderConfig {

String SSE_TRANSPORT = "sse";

String DISCONNECT = "close";

/**
* When a unexpected error occurs.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2012 Jeanfrancois Arcand
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.atmosphere.interceptor;

import org.atmosphere.cpr.Action;
import org.atmosphere.cpr.AtmosphereConfig;
import org.atmosphere.cpr.AtmosphereInterceptor;
import org.atmosphere.cpr.AtmosphereRequest;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.atmosphere.cpr.AtmosphereResourceEventImpl;
import org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter;
import org.atmosphere.cpr.AtmosphereResourceFactory;
import org.atmosphere.cpr.AtmosphereResourceImpl;
import org.atmosphere.cpr.HeaderConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
* When the browser close the connection, the atmosphere.js will send an unsubscribe message to tell
* framework the browser is disconnecting.
*
* @author Jeanfrancois Arcand
*/
public class OnDisconnectInterceptor implements AtmosphereInterceptor {

private final Logger logger = LoggerFactory.getLogger(OnDisconnectInterceptor.class);

@Override
public void configure(AtmosphereConfig config) {
}

@Override
public Action inspect(final AtmosphereResource r) {
AtmosphereRequest request = r.getRequest();
String s = request.getHeader(HeaderConfig.X_ATMOSPHERE_TRANSPORT);
String uuid = request.getHeader(HeaderConfig.X_ATMOSPHERE_TRACKING_ID);
if (s != null && uuid != null && s.equalsIgnoreCase(HeaderConfig.DISCONNECT)) {
logger.debug("AtmosphereResource {} disconnected", uuid);
AtmosphereResource ss = AtmosphereResourceFactory.getDefault().find(uuid);
if (ss != null) {
ss.notifyListeners(new AtmosphereResourceEventImpl(AtmosphereResourceImpl.class.cast(r), true, false));
try {
ss.getRequest().setAttribute(AtmosphereResourceImpl.PRE_SUSPEND, "");
AtmosphereResourceImpl.class.cast(ss).cancel();
} catch (IOException e) {
logger.trace("", e);
}
}
return Action.CANCELLED;
}
return Action.CONTINUE;
}

@Override
public void postInspect(AtmosphereResource r) {
}

public String toString(){
return "Browser disconnection detection";
}
}
5 changes: 5 additions & 0 deletions modules/jquery/src/main/webapp/jquery/jquery.atmosphere.js
Original file line number Diff line number Diff line change
Expand Up @@ -2347,6 +2347,10 @@ jQuery.atmosphere = function() {
}
};

this.uuid = function() {
return _request.uuid;
}

this.pushLocal = function(message) {
_intraPush(message);
};
Expand Down Expand Up @@ -2392,6 +2396,7 @@ jQuery.atmosphere = function() {
var requestsClone = [].concat(jQuery.atmosphere.requests);
for (var i = 0; i < requestsClone.length; i++) {
var rq = requestsClone[i];
jQuery.ajax({url: rq.getUrl() + "?X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=" + rq.uuid(), async:false});
rq.close();
clearTimeout(rq.id);
}
Expand Down

0 comments on commit 8a81a48

Please sign in to comment.