/** * 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.transport; import java.net.SocketAddress; import java.util.Arrays; import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.corundumstudio.socketio.AckCallback; import com.corundumstudio.socketio.HandshakeData; import com.corundumstudio.socketio.SocketIOClient; import com.corundumstudio.socketio.Transport; import com.corundumstudio.socketio.handler.ClientHead; import com.corundumstudio.socketio.namespace.Namespace; import com.corundumstudio.socketio.protocol.Packet; import com.corundumstudio.socketio.protocol.PacketType; public class NamespaceClient implements SocketIOClient { private static final Logger log = LoggerFactory.getLogger(NamespaceClient.class); private final AtomicBoolean disconnected = new AtomicBoolean(); private final ClientHead baseClient; private final Namespace namespace; public NamespaceClient(ClientHead baseClient, Namespace namespace) { this.baseClient = baseClient; this.namespace = namespace; namespace.addClient(this); } public ClientHead getBaseClient() { return baseClient; } @Override public Transport getTransport() { return baseClient.getCurrentTransport(); } @Override public boolean isChannelOpen() { return baseClient.isChannelOpen(); } @Override public Namespace getNamespace() { return namespace; } @Override public void sendEvent(String name, Object ... data) { Packet packet = new Packet(PacketType.MESSAGE); packet.setSubType(PacketType.EVENT); packet.setName(name); packet.setData(Arrays.asList(data)); send(packet); } @Override public void sendEvent(String name, AckCallback<?> ackCallback, Object ... data) { Packet packet = new Packet(PacketType.MESSAGE); packet.setSubType(PacketType.EVENT); packet.setName(name); packet.setData(Arrays.asList(data)); send(packet, ackCallback); } private boolean isConnected() { return !disconnected.get() && baseClient.isConnected(); } @Override public void send(Packet packet, AckCallback<?> ackCallback) { if (!isConnected()) { ackCallback.onTimeout(); return; } long index = baseClient.getAckManager().registerAck(getSessionId(), ackCallback); packet.setAckId(index); send(packet); } @Override public void send(Packet packet) { if (!isConnected()) { return; } packet.setNsp(namespace.getName()); baseClient.send(packet); } public void onDisconnect() { disconnected.set(true); baseClient.removeNamespaceClient(this); namespace.onDisconnect(this); log.debug("Client {} for namespace {} has been disconnected", baseClient.getSessionId(), getNamespace().getName()); } @Override public void disconnect() { Packet packet = new Packet(PacketType.MESSAGE); packet.setSubType(PacketType.DISCONNECT); send(packet); // onDisconnect(); } @Override public UUID getSessionId() { return baseClient.getSessionId(); } @Override public SocketAddress getRemoteAddress() { return baseClient.getRemoteAddress(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((getSessionId() == null) ? 0 : getSessionId().hashCode()); result = prime * result + ((getNamespace().getName() == null) ? 0 : getNamespace().getName().hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; NamespaceClient other = (NamespaceClient) obj; if (getSessionId() == null) { if (other.getSessionId() != null) return false; } else if (!getSessionId().equals(other.getSessionId())) return false; if (getNamespace().getName() == null) { if (other.getNamespace().getName() != null) return false; } else if (!getNamespace().getName().equals(other.getNamespace().getName())) return false; return true; } @Override public void joinRoom(String room) { namespace.joinRoom(room, getSessionId()); } @Override public void leaveRoom(String room) { namespace.leaveRoom(room, getSessionId()); } @Override public void set(String key, Object val) { baseClient.getStore().set(key, val); } @Override public <T> T get(String key) { return baseClient.getStore().get(key); } @Override public boolean has(String key) { return baseClient.getStore().has(key); } @Override public void del(String key) { baseClient.getStore().del(key); } @Override public Set<String> getAllRooms() { return namespace.getRooms(this); } @Override public HandshakeData getHandshakeData() { return baseClient.getHandshakeData(); } }