/**
* Copyright 2015 ArcBees Inc.
*
* 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 com.arcbees.gaestudio.client.application.channel;
import java.util.List;
import javax.inject.Inject;
import com.arcbees.gaestudio.client.rest.ChannelService;
import com.arcbees.gaestudio.client.util.AsyncCallbackImpl;
import com.arcbees.gaestudio.shared.channel.Token;
import com.arcbees.gaestudio.shared.channel.Topic;
import com.google.gwt.appengine.channel.client.Channel;
import com.google.gwt.appengine.channel.client.ChannelError;
import com.google.gwt.appengine.channel.client.ChannelFactory;
import com.google.gwt.appengine.channel.client.Socket;
import com.google.gwt.appengine.channel.client.SocketListener;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.gwtplatform.dispatch.rest.client.RestDispatch;
import com.gwtplatform.dispatch.rest.shared.RestAction;
import static com.google.common.collect.Lists.newArrayList;
public class ChannelHandler implements SocketListener {
public interface ChannelOpenCallback {
void onChannelOpen();
}
private final ChannelFactory channelFactory;
private final ChannelService channelService;
private final RestDispatch dispatch;
private final List<ChannelOpenCallback> callbacks;
private final MessageHandlers messageHandlers;
private Socket socket;
private boolean channelOpen;
@Inject
ChannelHandler(
ChannelService channelService,
RestDispatch dispatch,
ChannelFactory channelFactory,
MessageHandlers messageHandlers) {
this.channelFactory = channelFactory;
this.dispatch = dispatch;
this.channelService = channelService;
this.messageHandlers = messageHandlers;
callbacks = newArrayList();
}
public void openChannel(ChannelOpenCallback callback) {
if (isChannelOpen()) {
callback.onChannelOpen();
return;
}
callbacks.add(callback);
RestAction<Token> action = channelService.getToken();
dispatch.execute(action, new AsyncCallbackImpl<Token>() {
@Override
public void onSuccess(Token token) {
Channel channel = channelFactory.createChannel(token.getValue());
socket = channel.open(ChannelHandler.this);
}
});
}
public void closeChannel() {
if (socket != null) {
socket.close();
}
}
public boolean isChannelOpen() {
return channelOpen;
}
@Override
public void onOpen() {
for (ChannelOpenCallback callback : callbacks) {
callback.onChannelOpen();
}
channelOpen = true;
}
@Override
public void onMessage(String json) {
JSONValue jsonValue = JSONParser.parseStrict(json);
JSONObject jsonObject = jsonValue.isObject();
String topicString = jsonObject.get("topic").isString().stringValue();
Topic topic = Topic.valueOf(topicString);
JSONValue payload = jsonObject.get("payload");
messageHandlers.handle(topic, payload);
}
@Override
public void onError(ChannelError channelError) {
}
@Override
public void onClose() {
channelOpen = false;
}
}