/** * Copyright 2012 Ronen Hamias, Anton Kharenko * * 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 io.scalecube.socketio.session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.SocketAddress; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import io.netty.channel.Channel; import io.scalecube.socketio.TransportType; import io.scalecube.socketio.packets.ConnectPacket; import io.scalecube.socketio.pipeline.UnsupportedTransportTypeException; /** * * @author Anton Kharenko * */ public class SessionStorage { private final Logger log = LoggerFactory.getLogger(getClass()); private final ConcurrentMap<String, ManagedSession> sessions = new ConcurrentHashMap<>(); private final int localPort; public SessionStorage(int localPort) { this.localPort = localPort; } public boolean containSession(final String sessionId) { return sessions.containsKey(sessionId); } public void removeSession(final String sessionId) { sessions.remove(sessionId); } public ManagedSession getSession(final ConnectPacket connectPacket, final Channel channel, final SessionDisconnectHandler disconnectHandler) throws Exception { ManagedSession session = getOrCreateSession(connectPacket, channel, disconnectHandler, null); // If transport protocol was changed then remove old session and create new one instead if (connectPacket.getTransportType() != session.getTransportType()) { session.markAsUpgraded(); String oldSessionId = session.getSessionId(); TransportType oldTransportType = session.getTransportType(); final String sessionId = connectPacket.getSessionId(); removeSession(sessionId); session = getOrCreateSession(connectPacket, channel, disconnectHandler, session.getTransportType()); if (log.isDebugEnabled()) log.debug("{} transport type {} session was upgraded to new transport type {} and session {}", oldTransportType.name(), oldSessionId, session.getTransportType().name(), session.getSessionId()); } return session; } private ManagedSession getOrCreateSession(final ConnectPacket connectPacket, final Channel channel, final SessionDisconnectHandler disconnectHandler, final TransportType upgradedFromTransportType) throws Exception { final String sessionId = connectPacket.getSessionId(); ManagedSession session = sessions.get(sessionId); if (session == null) { session = createSession(connectPacket, channel, disconnectHandler, upgradedFromTransportType); ManagedSession fasterSession = sessions.putIfAbsent(sessionId, session); if (fasterSession != null) { session = fasterSession; } } return session; } private ManagedSession createSession(final ConnectPacket connectPacket, final Channel channel, final SessionDisconnectHandler disconnectHandler, final TransportType upgradedFromTransportType) throws Exception { final TransportType transportType = connectPacket.getTransportType(); final String sessionId = connectPacket.getSessionId(); final String origin = connectPacket.getOrigin(); final String jsonpIndexParam = connectPacket.getJsonpIndexParam(); final SocketAddress remoteAddress = connectPacket.getRemoteAddress(); // Create session by transport type switch(transportType) { case WEBSOCKET: return new WebSocketSession(channel, sessionId, origin, disconnectHandler, upgradedFromTransportType, localPort, remoteAddress); case FLASHSOCKET: return new FlashSocketSession(channel, sessionId, origin, disconnectHandler, upgradedFromTransportType, localPort, remoteAddress); case XHR_POLLING: return new XHRPollingSession(channel, sessionId, origin, disconnectHandler, upgradedFromTransportType, localPort, remoteAddress); case JSONP_POLLING: return new JsonpPollingSession(channel, sessionId, origin, disconnectHandler, upgradedFromTransportType, localPort, jsonpIndexParam, remoteAddress); default: throw new UnsupportedTransportTypeException(transportType); } } public ManagedSession getSessionIfExist(final String sessionId) { return sessions.get(sessionId); } }