SocketIOServiceImpl.java 5.68 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Deactivate
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.socketio.impl;

import com.adobe.granite.socketio.SocketIOListener;
import com.adobe.granite.socketio.SocketIONamespace;
import com.adobe.granite.socketio.SocketIOService;
import com.adobe.granite.socketio.SocketIOSocket;
import com.adobe.granite.socketio.impl.Client;
import com.adobe.granite.socketio.impl.SocketIONamespaceImpl;
import com.adobe.granite.socketio.impl.SocketIOSocketImpl;
import com.adobe.granite.socketio.impl.engine.EIOListener;
import com.adobe.granite.socketio.impl.engine.EIOService;
import com.adobe.granite.socketio.impl.engine.EIOSocket;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
@Service(value={SocketIOService.class})
public class SocketIOServiceImpl
implements SocketIOService,
EIOListener {
    private static final Logger log = LoggerFactory.getLogger(SocketIOServiceImpl.class);
    private final ConcurrentMap<SocketIOListener, Object> listeners = new ConcurrentHashMap<SocketIOListener, Object>();
    private final ConcurrentMap<String, Client> clients = new ConcurrentHashMap<String, Client>();
    private final ConcurrentMap<String, SocketIONamespaceImpl> namespaces = new ConcurrentHashMap<String, SocketIONamespaceImpl>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private long callbackTimeout = 60000;
    @Reference
    private EIOService engine;

    @Activate
    private void activate() {
        this.engine.register(this);
    }

    @Deactivate
    private void deactivate() {
        this.engine.unregister(this);
        for (Client client : this.clients.values().toArray(new Client[this.clients.size()])) {
            client.disconnect();
        }
    }

    public void detach(Client client) {
        this.clients.remove(client.getId());
    }

    @Override
    public void onConnect(EIOSocket socket) {
        log.debug("[{}] onConnect()", (Object)socket.getId());
        if (this.clients.containsKey(socket.getId())) {
            log.error("Unable to process connection of socket {}. Client already exists.");
            return;
        }
        Client client = new Client(socket.getId(), this, socket);
        this.clients.put(client.getId(), client);
        client.connect("/");
    }

    @Override
    public void onDisconnect(EIOSocket socket) {
    }

    public SocketIONamespaceImpl getNamespace(String nsp, boolean create) {
        SocketIONamespaceImpl ns = this.namespaces.get(nsp);
        if (ns == null) {
            if (!create) {
                throw new IllegalArgumentException("no such namespace " + nsp);
            }
            if (this.namespaces.putIfAbsent(nsp, new SocketIONamespaceImpl(nsp)) == null) {
                log.debug("Created new namespace: {}", (Object)nsp);
            }
            ns = this.namespaces.get(nsp);
        }
        return ns;
    }

    public void onConnect(SocketIOSocketImpl socket) {
        String nsp = socket.getNamespace().getName();
        for (SocketIOListener l : this.listeners.keySet()) {
            if (!l.handleNamespace(nsp)) continue;
            try {
                l.onConnect(socket);
            }
            catch (Exception e) {
                log.warn("Listener threw exception", (Throwable)e);
            }
        }
        if (!socket.hasListener()) {
            log.warn("[{}] No listener attached to socket for namespace {}. closing.", (Object)socket.getId(), (Object)nsp);
            socket.disconnect(false);
        }
    }

    public void onDisconnect(SocketIOSocket socket, String reason) {
        for (SocketIOListener l : this.listeners.keySet()) {
            if (!l.handleNamespace(socket.getNamespace().getName())) continue;
            try {
                l.onDisconnect(socket, reason);
            }
            catch (Exception e) {
                log.warn("Listener threw exception", (Throwable)e);
            }
        }
    }

    protected ScheduledFuture<?> scheduleCallbackTimeout(Runnable timeoutHandler, long timeout) {
        if (timeout <= 0) {
            timeout = this.callbackTimeout;
        }
        return this.scheduler.schedule(timeoutHandler, timeout, TimeUnit.MILLISECONDS);
    }

    @Override
    public void register(SocketIOListener listener) {
        this.listeners.put(listener, listener);
    }

    @Override
    public void unregister(SocketIOListener listener) {
        this.listeners.remove(listener);
    }

    @Override
    public Map<String, SocketIONamespace> getNamespaces() {
        return Collections.unmodifiableMap(this.namespaces);
    }

    protected void bindEngine(EIOService eIOService) {
        this.engine = eIOService;
    }

    protected void unbindEngine(EIOService eIOService) {
        if (this.engine == eIOService) {
            this.engine = null;
        }
    }
}