com.corundumstudio.socketio.ack.AckManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netty-socketio Show documentation
Show all versions of netty-socketio Show documentation
Socket.IO server implemented on Java
/**
* Copyright 2012 Nikita Koksharov
*
* 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.corundumstudio.socketio.ack;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.corundumstudio.socketio.AckCallback;
import com.corundumstudio.socketio.Disconnectable;
import com.corundumstudio.socketio.MultiTypeAckCallback;
import com.corundumstudio.socketio.MultiTypeArgs;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.handler.ClientHead;
import com.corundumstudio.socketio.protocol.Packet;
import com.corundumstudio.socketio.scheduler.CancelableScheduler;
import com.corundumstudio.socketio.scheduler.SchedulerKey;
import com.corundumstudio.socketio.scheduler.SchedulerKey.Type;
public class AckManager implements Disconnectable {
class AckEntry {
final Map> ackCallbacks = new ConcurrentHashMap>();
final AtomicLong ackIndex = new AtomicLong(-1);
public long addAckCallback(AckCallback> callback) {
long index = ackIndex.incrementAndGet();
ackCallbacks.put(index, callback);
return index;
}
public Set getAckIndexes() {
return ackCallbacks.keySet();
}
public AckCallback> getAckCallback(long index) {
return ackCallbacks.get(index);
}
public AckCallback> removeCallback(long index) {
return ackCallbacks.remove(index);
}
public void initAckIndex(long index) {
ackIndex.compareAndSet(-1, index);
}
}
private final Logger log = LoggerFactory.getLogger(getClass());
private final Map ackEntries = new ConcurrentHashMap();
private final CancelableScheduler scheduler;
public AckManager(CancelableScheduler scheduler) {
super();
this.scheduler = scheduler;
}
public void initAckIndex(UUID sessionId, long index) {
AckEntry ackEntry = getAckEntry(sessionId);
ackEntry.initAckIndex(index);
}
private AckEntry getAckEntry(UUID sessionId) {
AckEntry ackEntry = ackEntries.get(sessionId);
if (ackEntry == null) {
ackEntry = new AckEntry();
AckEntry oldAckEntry = ackEntries.put(sessionId, ackEntry);
if (oldAckEntry != null) {
ackEntry = oldAckEntry;
}
}
return ackEntry;
}
public void onAck(SocketIOClient client, Packet packet) {
AckSchedulerKey key = new AckSchedulerKey(Type.ACK_TIMEOUT, client.getSessionId(), packet.getAckId());
scheduler.cancel(key);
AckCallback callback = removeCallback(client.getSessionId(), packet.getAckId());
if (callback == null) {
return;
}
if (callback instanceof MultiTypeAckCallback) {
callback.onSuccess(new MultiTypeArgs(packet.>getData()));
} else {
Object param = null;
List