Repository: incubator-wave Updated Branches: refs/heads/master d35211be5 -> 050fbb412
http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/38bc93ea/wave/src/main/java/org/waveprotocol/box/server/rpc/ServerRpcProvider.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/rpc/ServerRpcProvider.java b/wave/src/main/java/org/waveprotocol/box/server/rpc/ServerRpcProvider.java index c256199..8d59a61 100755 --- a/wave/src/main/java/org/waveprotocol/box/server/rpc/ServerRpcProvider.java +++ b/wave/src/main/java/org/waveprotocol/box/server/rpc/ServerRpcProvider.java @@ -19,28 +19,25 @@ package org.waveprotocol.box.server.rpc; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.inject.Inject; -import com.google.inject.Injector; -import com.google.inject.Singleton; -import com.google.inject.servlet.GuiceFilter; -import com.google.inject.servlet.GuiceServletContextListener; -import com.google.inject.servlet.ServletModule; -import com.google.protobuf.Descriptors; -import com.google.protobuf.Descriptors.MethodDescriptor; -import com.google.protobuf.Message; -import com.google.protobuf.RpcCallback; -import com.google.protobuf.Service; -import com.typesafe.config.Config; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executor; + +import javax.annotation.Nullable; +import javax.servlet.DispatcherType; +import javax.servlet.Filter; +import javax.servlet.ServletContextListener; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpSession; + import org.apache.commons.lang.StringUtils; -import org.atmosphere.cache.UUIDBroadcasterCache; -import org.atmosphere.config.service.AtmosphereHandlerService; -import org.atmosphere.cpr.*; -import org.atmosphere.guice.AtmosphereGuiceServlet; -import org.atmosphere.util.IOUtils; import org.eclipse.jetty.proxy.ProxyServlet; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; @@ -52,14 +49,16 @@ import org.eclipse.jetty.servlets.GzipFilter; import org.eclipse.jetty.util.resource.ResourceCollection; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.webapp.WebAppContext; -import org.eclipse.jetty.websocket.servlet.*; +import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; +import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; +import org.eclipse.jetty.websocket.servlet.WebSocketCreator; +import org.eclipse.jetty.websocket.servlet.WebSocketServlet; +import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolAuthenticate; import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolAuthenticationResult; import org.waveprotocol.box.server.authentication.SessionManager; import org.waveprotocol.box.server.executor.ExecutorAnnotations.ClientServerExecutor; import org.waveprotocol.box.server.persistence.file.FileUtils; -import org.waveprotocol.box.server.rpc.atmosphere.AtmosphereChannel; -import org.waveprotocol.box.server.rpc.atmosphere.AtmosphereClientInterceptor; import org.waveprotocol.box.server.util.NetUtils; import org.waveprotocol.box.stat.Timer; import org.waveprotocol.box.stat.Timing; @@ -67,18 +66,22 @@ import org.waveprotocol.wave.model.util.Pair; import org.waveprotocol.wave.model.wave.ParticipantId; import org.waveprotocol.wave.util.logging.Log; -import javax.annotation.Nullable; -import javax.servlet.DispatcherType; -import javax.servlet.Filter; -import javax.servlet.ServletContextListener; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpSession; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executor; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.google.inject.Singleton; +import com.google.inject.servlet.GuiceFilter; +import com.google.inject.servlet.GuiceServletContextListener; +import com.google.inject.servlet.ServletModule; +import com.google.protobuf.Descriptors; +import com.google.protobuf.Descriptors.MethodDescriptor; +import com.google.protobuf.Message; +import com.google.protobuf.RpcCallback; +import com.google.protobuf.Service; +import com.typesafe.config.Config; /** * ServerRpcProvider can provide instances of type Service over an incoming @@ -146,32 +149,6 @@ public class ServerRpcProvider { } } - static class AtmosphereConnection extends Connection { - - private final AtmosphereChannel atmosphereChannel; - - public AtmosphereConnection(ParticipantId loggedInUser, ServerRpcProvider provider) { - super(loggedInUser, provider); - - atmosphereChannel = new AtmosphereChannel(this); - expectMessages(atmosphereChannel); - - } - - @Override - protected void sendMessage(int sequenceNo, Message message) { - atmosphereChannel.sendMessage(sequenceNo, message); - } - - public AtmosphereChannel getAtmosphereChannel() { - return atmosphereChannel; - } - - - } - - - static abstract class Connection implements ProtoCallback { private final Map<Integer, ServerRpcController> activeRpcs = new ConcurrentHashMap<>(); @@ -409,16 +386,6 @@ public class ServerRpcProvider { // TODO(zamfi): fix to let messages span frames. wsholder.setInitParameter("bufferSize", "" + BUFFER_SIZE); - // Atmosphere framework. Replacement of Socket.IO - // See https://issues.apache.org/jira/browse/WAVE-405 - ServletHolder atholder = addServlet("/atmosphere*", AtmosphereGuiceServlet.class); - // Enable guice. See - // https://github.com/Atmosphere/atmosphere/wiki/Configuring-Atmosphere%27s-Classes-Creation-and-Injection - atholder.setInitParameter("org.atmosphere.cpr.objectFactory", - "org.waveprotocol.box.server.rpc.atmosphere.GuiceAtmosphereFactory"); - atholder.setAsyncSupported(true); - atholder.setInitOrder(0); - // Serve the static content and GWT web client with the default servlet // (acts like a standard file-based web server). addServlet("/static/*", DefaultServlet.class); @@ -566,178 +533,6 @@ public class ServerRpcProvider { } /** - * Manange atmosphere connections and dispatch messages to - * wave channels. - * - * @author [email protected] <Pablo Ojanguren> - * - */ - @Singleton - @AtmosphereHandlerService(path = "/atmosphere", - interceptors = {AtmosphereClientInterceptor.class}, - broadcasterCache = UUIDBroadcasterCache.class) - public static class WaveAtmosphereService implements AtmosphereHandler { - - - private static final Log LOG = Log.get(WaveAtmosphereService.class); - - private static final String WAVE_CHANNEL_ATTRIBUTE = "WAVE_CHANNEL_ATTRIBUTE"; - private static final String MSG_SEPARATOR = "|"; - private static final String MSG_CHARSET = "UTF-8"; - - @Inject - public ServerRpcProvider provider; - - - @Override - public void onRequest(AtmosphereResource resource) throws IOException { - - AtmosphereResourceSession resourceSession = - AtmosphereResourceSessionFactory.getDefault().getSession(resource); - - AtmosphereChannel resourceChannel = - resourceSession.getAttribute(WAVE_CHANNEL_ATTRIBUTE, AtmosphereChannel.class); - - if (resourceChannel == null) { - - ParticipantId loggedInUser = - provider.sessionManager.getLoggedInUser(resource.getRequest().getSession(false)); - - AtmosphereConnection connection = new AtmosphereConnection(loggedInUser, provider); - resourceChannel = connection.getAtmosphereChannel(); - resourceSession.setAttribute(WAVE_CHANNEL_ATTRIBUTE, resourceChannel); - resourceChannel.onConnect(resource); - } - - resource.setBroadcaster(resourceChannel.getBroadcaster()); // on every - // request - - if (resource.getRequest().getMethod().equalsIgnoreCase("GET")) { - - resource.suspend(); - - } - - - if (resource.getRequest().getMethod().equalsIgnoreCase("POST")) { - - StringBuilder b = IOUtils.readEntirely(resource); - resourceChannel.onMessage(b.toString()); - - } - - } - - - @Override - public void onStateChange(AtmosphereResourceEvent event) throws IOException { - - - AtmosphereResponse response = event.getResource().getResponse(); - AtmosphereResource resource = event.getResource(); - - if (event.isSuspended()) { - - // Set content type before do response.getWriter() - // http://docs.oracle.com/javaee/5/api/javax/servlet/ServletResponse.html#setContentType(java.lang.String) - response.setContentType("text/plain; charset=UTF-8"); - response.setCharacterEncoding("UTF-8"); - - - if (event.getMessage().getClass().isArray()) { - - LOG.fine("SEND MESSAGE ARRAY " + event.getMessage().toString()); - - List<Object> list = Collections.singletonList(event.getMessage()); - - response.getOutputStream().write(MSG_SEPARATOR.getBytes(MSG_CHARSET)); - for (Object object : list) { - String message = (String) object; - message += MSG_SEPARATOR; - response.getOutputStream().write(message.getBytes(MSG_CHARSET)); - } - - } else if (event.getMessage() instanceof List) { - - LOG.fine("SEND MESSAGE LIST " + event.getMessage().toString()); - - @SuppressWarnings("unchecked") - List<Object> list = List.class.cast(event.getMessage()); - - response.getOutputStream().write(MSG_SEPARATOR.getBytes(MSG_CHARSET)); - for (Object object : list) { - String message = (String) object; - message += MSG_SEPARATOR; - response.getOutputStream().write(message.getBytes(MSG_CHARSET)); - } - - } else if (event.getMessage() instanceof String) { - - LOG.fine("SEND MESSAGE " + event.getMessage().toString()); - - String message = (String) event.getMessage(); - response.getOutputStream().write(message.getBytes(MSG_CHARSET)); - } - - - - try { - - response.flushBuffer(); - - switch (resource.transport()) { - case JSONP: - case LONG_POLLING: - event.getResource().resume(); - break; - case WEBSOCKET: - case STREAMING: - case SSE: - response.getOutputStream().flush(); - break; - default: - LOG.info("Unknown transport"); - break; - } - } catch (IOException e) { - LOG.info("Error resuming resource response", e); - } - - - } else if (event.isResuming()) { - - LOG.fine("RESUMING"); - - } else if (event.isResumedOnTimeout()) { - - LOG.fine("RESUMED ON TIMEOUT"); - - } else if (event.isClosedByApplication() || event.isClosedByClient()) { - - LOG.fine("CONNECTION CLOSED"); - - AtmosphereResourceSession resourceSession = - AtmosphereResourceSessionFactory.getDefault().getSession(resource); - - AtmosphereChannel resourceChannel = - resourceSession.getAttribute(WAVE_CHANNEL_ATTRIBUTE, AtmosphereChannel.class); - - if (resourceChannel != null) { - resourceChannel.onDisconnect(); - } - } - } - - @Override - public void destroy() { - // Nothing to do - - } - - - } - - /** * Returns the socket the WebSocket server is listening on. */ public SocketAddress getWebSocketAddress() { http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/38bc93ea/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereChannel.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereChannel.java b/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereChannel.java deleted file mode 100644 index 4bc9adb..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereChannel.java +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.rpc.atmosphere; - - -import org.atmosphere.cpr.AtmosphereResource; -import org.atmosphere.cpr.Broadcaster; -import org.atmosphere.cpr.BroadcasterFactory; -import org.waveprotocol.box.server.rpc.ProtoCallback; -import org.waveprotocol.box.server.rpc.WebSocketChannel; -import org.waveprotocol.wave.util.logging.Log; - -import java.io.IOException; - -/** - * An atmosphere wrapper for the WebSocketChannel type. - * - * @author [email protected] (Pablo Ojanguren) - */ -public class AtmosphereChannel extends WebSocketChannel { - - - private static final Log LOG = Log.get(AtmosphereChannel.class); - - /* The object needed to send messages out */ - private Broadcaster broadcaster; - - - - /** - * Creates a new AtmosphereChannel using the callback for incoming messages. - * - * @param callback A ProtoCallback instance called with incoming messages. - */ - public AtmosphereChannel(ProtoCallback callback) { - super(callback); - broadcaster = BroadcasterFactory.getDefault().get(); - - } - - /** - * A new resource connection has been associated with - * this channel - * @param resource the Atmosphere resource object - */ - public void onConnect(AtmosphereResource resource) { - - // Create a new broadcaster to publish to this resource - broadcaster.addAtmosphereResource(resource); - } - - - public Broadcaster getBroadcaster() { - return broadcaster; - } - - /** - * The atmosphere resource has received a new post message - * @param message the message - */ - public void onMessage(String message) { - - handleMessageString(message); - } - - /** - * The atmosphere resource has been closed - */ - public void onDisconnect() { - - broadcaster = null; - } - - - - /** - * Send the given data String - * - * @param data - * @throws IOException - */ - @Override - protected void sendMessageString(String data) throws IOException { - - if (broadcaster == null || broadcaster.isDestroyed()) { - // Just drop the message. It's rude to throw an exception since the - // caller had no way of knowing. - LOG.warning("Atmosphere Channel is not connected"); - } else { - - LOG.fine("BROADCAST "+data); - broadcaster.broadcast(data); - } - } - - - - -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/38bc93ea/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereClientInterceptor.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereClientInterceptor.java b/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereClientInterceptor.java deleted file mode 100644 index 12468d3..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereClientInterceptor.java +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.rpc.atmosphere; - - - -import com.google.common.io.ByteStreams; - -import org.atmosphere.config.service.AtmosphereInterceptorService; -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.waveprotocol.wave.util.logging.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - - /** - * Serve atmosphere.js file to GWT clients This class allows to serve the - * Atmosphere Javascript client from the same /atmosphere servlet path which is - * used to process any Atmosphere request instead of place it on the /static - * path. In addition, the Javascript file is put together with the rest of - * Atmosphere related source code, during the build process as any other third - * party dependency. - * - * - * @author [email protected] (Pablo Ojanguren) - */ - @AtmosphereInterceptorService - public class AtmosphereClientInterceptor implements AtmosphereInterceptor { - - private static final Log LOG = Log.get(AtmosphereClientInterceptor.class); - - @Override - public void configure(AtmosphereConfig config) { - // Nothing to do - } - - @Override - public Action inspect(AtmosphereResource resource) { - - AtmosphereRequest request = resource.getRequest(); - - try { - // Find the first context parameter - String path = request.getPathInfo(); - - if (path == null || path.isEmpty()) - return Action.CONTINUE; - - if (path.startsWith("/")) { - path = path.substring(1); - } - String[] parts = path.split("/"); - - // Serve the file - if (parts.length > 0 && "GET".equals(resource.getRequest().getMethod()) && "atmosphere.js".equals(parts[0])) { - resource.getResponse().setContentType("text/javascript"); - InputStream is = - this.getClass().getClassLoader() - .getResourceAsStream("org/waveprotocol/box/server/rpc/atmosphere/atmosphere.js"); - OutputStream os = resource.getResponse().getOutputStream(); - ByteStreams.copy(is, os); - return Action.CANCELLED; - - } - - - } catch (IOException e) { - LOG.severe("Error sending atmosphere.js",e); - } - - - return Action.CONTINUE; - } - - - @Override - public void postInspect(AtmosphereResource resource) { - // Nothing to do - } - - } http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/38bc93ea/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/GuiceAtmosphereFactory.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/GuiceAtmosphereFactory.java b/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/GuiceAtmosphereFactory.java deleted file mode 100644 index 3611caf..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/GuiceAtmosphereFactory.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.rpc.atmosphere; - -import com.google.inject.Injector; - -import org.atmosphere.cpr.AtmosphereFramework; -import org.atmosphere.cpr.AtmosphereObjectFactory; -import org.waveprotocol.wave.util.logging.Log; - -/** - * Custom factory to use wave's guice injector in Atmosphere - * - * @author [email protected] (Pablo Ojanguren) - * - */ -public class GuiceAtmosphereFactory implements AtmosphereObjectFactory { - - private static final Log LOG = Log.get(GuiceAtmosphereFactory.class); - - private static Injector injector; - - @SuppressWarnings("unchecked") - @Override - public <T, U extends T> U newClassInstance(AtmosphereFramework framework, Class<T> classType, Class<U> classToInstantiate) throws InstantiationException, IllegalAccessException { - initInjector(framework); - - - if (injector == null) { - return classToInstantiate.newInstance(); - } else { - return injector.getInstance(classToInstantiate); - } - } - - public String toString() { - return "Guice ObjectFactory"; - } - - private void initInjector(AtmosphereFramework framework) { - if (injector == null) { - com.google.inject.Injector servletInjector = (com.google.inject.Injector) - framework.getServletContext().getAttribute( - com.google.inject.Injector.class.getName()); - - if (servletInjector != null) { - injector = servletInjector; - LOG.fine("Existing injector found to create Atmosphere instances"); - } else { - LOG.fine("Not injector not found to create Atmosphere instances"); - } - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/38bc93ea/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveSocketFactory.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveSocketFactory.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveSocketFactory.java index d79ce4e..20d2bce 100644 --- a/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveSocketFactory.java +++ b/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveSocketFactory.java @@ -22,14 +22,9 @@ package org.waveprotocol.box.webclient.client; import com.google.gwt.websockets.client.WebSocket; import com.google.gwt.websockets.client.WebSocketCallback; -import org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnection; -import org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionImpl; -import org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionListener; - /** - * Factory to create proxy wrappers around either {@link com.google.gwt.websockets.client.WebSocket} - * or {@link org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnection}. + * Factory to create proxy wrappers for {@link com.google.gwt.websockets.client.WebSocket} * * @author [email protected] (Tad Glines) */ @@ -37,52 +32,10 @@ public class WaveSocketFactory { /** * Create a WaveSocket instance that wraps a concrete socket implementation. - * If useWebSocketAlt is true an instance of {@link org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnection} - * is wrapped, otherwise an instance of {@link com.google.gwt.websockets.client.WebSocket} is - * wrapped. */ - public static WaveSocket create(boolean useWebSocketAlt, final String urlBase, + public static WaveSocket create(final String urlBase, final WaveSocket.WaveSocketCallback callback) { - if (useWebSocketAlt) { - return new WaveSocket() { - - private final AtmosphereConnection socket - = new AtmosphereConnectionImpl(new AtmosphereConnectionListener() { - - @Override - public void onConnect() { - callback.onConnect(); - } - - @Override - public void onDisconnect() { - callback.onDisconnect(); - } - - @Override - public void onMessage(String message) { - callback.onMessage(message); - }}, urlBase); - - @Override - public void connect() { - socket.connect(); - - } - - @Override - public void disconnect() { - socket.close(); - } - - @Override - public void sendMessage(String message) { - socket.sendMessage(message); - } - - }; - } else { return new WaveSocket() { final WebSocket socket = new WebSocket(new WebSocketCallback() { @Override @@ -116,6 +69,5 @@ public class WaveSocketFactory { socket.send(message); } }; - } } } http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/38bc93ea/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveWebSocketClient.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveWebSocketClient.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveWebSocketClient.java index 167ea94..98350a3 100644 --- a/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveWebSocketClient.java +++ b/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveWebSocketClient.java @@ -114,11 +114,10 @@ public class WaveWebSocketClient implements WaveSocket.WaveSocketCallback { private final RepeatingCommand reconnectCommand = new RepeatingCommand() { @Override public boolean execute() { - if (!connectedAtLeastOnce && !websocketNotAvailable && connectTry > MAX_INITIAL_FAILURES) { - // Let's try to use websocket alternative, seems that websocket it's not working - // (we are under a proxy or similar) - socket = WaveSocketFactory.create(true, urlBase, WaveWebSocketClient.this); + if (connectTry > MAX_INITIAL_FAILURES) { + return false; } + connectTry++; if (connected == ConnectState.DISCONNECTED) { LOG.info("Attemping to reconnect"); @@ -128,16 +127,19 @@ public class WaveWebSocketClient implements WaveSocket.WaveSocketCallback { return true; } }; - private final boolean websocketNotAvailable; + private boolean connectedAtLeastOnce = false; private long connectTry = 0; private final String urlBase; public WaveWebSocketClient(boolean websocketNotAvailable, String urlBase) { - this.websocketNotAvailable = websocketNotAvailable; this.urlBase = urlBase; submitRequestCallbacks = CollectionUtils.createIntMap(); - socket = WaveSocketFactory.create(websocketNotAvailable, urlBase, this); + if (websocketNotAvailable) { + ClientEvents.get().fireEvent(new NetworkStatusEvent(ConnectionStatus.NEVER_CONNECTED)); + throw new RuntimeException("Websocket is not available"); + } + socket = WaveSocketFactory.create(urlBase, this); } /** http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/38bc93ea/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnection.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnection.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnection.java deleted file mode 100644 index 29b1f24..0000000 --- a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnection.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.webclient.client.atmosphere; - -/** - * The atmosphere connection interface for wrapping the javascript - * client in GWT - * - * @author [email protected] (Pablo Ojanguren) - * - */ -public interface AtmosphereConnection { - - - /** - * Initiate a connection attempt. - * - */ - void connect(); - - /** - * Initiate an orderly close of the connection. - * - */ - void close(); - - - /** - * Send a message. - * - * @param message - */ - void sendMessage(String message); - - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/38bc93ea/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionImpl.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionImpl.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionImpl.java deleted file mode 100644 index c405f18..0000000 --- a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionImpl.java +++ /dev/null @@ -1,232 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.webclient.client.atmosphere; - -import com.google.gwt.core.client.Callback; -import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.core.client.ScriptInjector; - -/** - * The wrapper implementation of the atmosphere javascript client. - * - * https://github.com/Atmosphere/atmosphere/wiki/jQuery.atmosphere.js-atmosphere - * .js-API - * - * More info about transports - * https://github.com/Atmosphere/atmosphere/wiki/Supported - * -WebServers-and-Browsers - * - * It tries to use Server-Sent Events first and fallback transport to - * long-polling. We ignore Websockets by now because they are the default - * transport on WiAB and atmosphere is the fallback. - * - * http://stackoverflow.com/questions/9397528/server-sent-events-vs-polling - * - * - * @author [email protected] (Pablo Ojanguren) - * - */ -public class AtmosphereConnectionImpl implements AtmosphereConnection { - - - private static final class AtmosphereSocket extends JavaScriptObject { - public static native AtmosphereSocket create(AtmosphereConnectionImpl impl, String urlBase) /*-{ - - var client = $wnd.atmosphere; - - var atsocket = { - request: null, - socket: null }; - - var connectionUrl = window.location.protocol + "//" + $wnd.__websocket_address + "/"; - - connectionUrl += 'atmosphere'; - - //console.log("Connection URL is "+urlBase); - atsocket.request = new client.AtmosphereRequest(); - atsocket.request.url = connectionUrl; - atsocket.request.contenType = 'text/plain;charset=UTF-8'; - atsocket.request.transport = 'sse'; - atsocket.request.fallbackTransport = 'long-polling'; - - atsocket.request.onOpen = $entry(function() { - im...@org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionImpl::onConnect()(); - }); - - atsocket.request.onMessage = $entry(function(response) { - - var r = response.responseBody; - - if (r.indexOf('|') == 0) { - - while (r.indexOf('|') == 0 && r.length > 1) { - - r = r.substring(1); - var marker = r.indexOf('}|'); - im...@org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionImpl::onMessage(Ljava/lang/String;)(r.substring(0, marker+1)); - r = r.substring(marker+1); - - } - - } - else { - - im...@org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionImpl::onMessage(Ljava/lang/String;)(r); - - } - - }); - - atsocket.request.onClose = $entry(function(response) { - - client.util.info("Connection closed"); - - im...@org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionImpl::onDisconnect(Ljava/lang/String;)(response); - }); - - - - atsocket.request.onTransportFailure = function(errorMsg, request) { - - client.util.info(errorMsg); - - }; - - - atsocket.request.onReconnect = function(request, response) { - - client.util.info("Reconnected to the server"); - - }; - - atsocket.request.onError = function(response) { - - client.util.info("Unexpected Error"); - - }; - - - return atsocket; - - - }-*/; - - protected AtmosphereSocket() { - } - - - public native void close() /*-{ - this.socket.unsubscribe(); - }-*/; - - public native AtmosphereSocket connect() /*-{ - this.socket = $wnd.atmosphere.subscribe(this.request); - - }-*/; - - public native void send(String data) /*-{ - this.socket.push(data); - }-*/; - } - - - private final AtmosphereConnectionListener listener; - private String urlBase; - private AtmosphereConnectionState state; - private AtmosphereSocket socket = null; - - public AtmosphereConnectionImpl(AtmosphereConnectionListener listener, - String urlBase) { - this.listener = listener; - this.urlBase = urlBase; - - } - - - @Override - public void connect() { - if (socket == null) { - - ScriptInjector.fromUrl("/atmosphere/atmosphere.js").setCallback( - new Callback<Void, Exception>() { - public void onFailure(Exception reason) { - throw new IllegalStateException("atmosphere.js load failed!"); - } - public void onSuccess(Void result) { - - socket = AtmosphereSocket.create(AtmosphereConnectionImpl.this, urlBase); - socket.connect(); - } - }).setWindow(ScriptInjector.TOP_WINDOW).inject(); - } else { - - - if (AtmosphereConnectionState.CLOSED.equals(this.state)) - socket.connect(); - - } - } - - @Override - public void close() { - if (!AtmosphereConnectionState.CLOSED.equals(this.state)) - socket.close(); - - } - - - @Override - public void sendMessage(String message) { - this.state = AtmosphereConnectionState.MESSAGE_PUBLISHED; - socket.send(message); - } - - - - @SuppressWarnings("unused") - private void onConnect() { - this.state = AtmosphereConnectionState.OPENED; - listener.onConnect(); - } - - /** - * This method is called when an Atmosphere onClose event happens: - * - * when an error occurs. when the server or a proxy closes the connection. - * when an expected exception occurs. when the specified transport is not - * supported or fail to connect. - * - * @param response - * - */ - @SuppressWarnings("unused") - private void onDisconnect(String response) { - this.state = AtmosphereConnectionState.CLOSED; - listener.onDisconnect(); - } - - @SuppressWarnings("unused") - private void onMessage(String message) { - this.state = AtmosphereConnectionState.MESSAGE_RECEIVED; - listener.onMessage(message); - } - - -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/38bc93ea/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionListener.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionListener.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionListener.java deleted file mode 100644 index aff7bfd..0000000 --- a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionListener.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.webclient.client.atmosphere; - -/** - * The listener interface for the atmosphere client wrapper. - * - * @author [email protected] (Pablo Ojanguren) - * - */ -public interface AtmosphereConnectionListener { - - /** - * Called when a successful connection with server is performed - */ - void onConnect(); - - /** - * Called when connection is closed properly or by error - */ - void onDisconnect(); - - /** - * Called when a new message is received from the server - * @param message - */ - void onMessage(String message); - - - -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/38bc93ea/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionState.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionState.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionState.java deleted file mode 100644 index a6b3c94..0000000 --- a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionState.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.webclient.client.atmosphere; - -/** - * Connection state definition inspired by former SocketIO/WebSocket - * implementation - * - * @author [email protected] (Pablo Ojanguren) - * - */ -public enum AtmosphereConnectionState { - - MESSAGE_RECEIVED("messageReceived"), - MESSAGE_PUBLISHED("messagePublished"), OPENED("opened"), - CLOSED("closed"), UNKNOWN("unknown"); - - private String value; - private AtmosphereConnectionState(String v) { this.value = v; } - public String value() { return value; } - - public static AtmosphereConnectionState fromString(String val) { - - if (val.equals("messageReceived")) { - return MESSAGE_RECEIVED; - } else if (val.equals("messagePublished")) { - return MESSAGE_PUBLISHED; - } else if (val.equals("opened")) { - return OPENED; - } else if (val.equals("closed")) { - return CLOSED; - } - - return UNKNOWN; - } -}
