/** *Copyright [2009-2010] [dennis zhuang(killme2008@gmail.com)] *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.google.code.hs4j.network.hs; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; import com.google.code.hs4j.Command; import com.google.code.hs4j.CommandFactory; import com.google.code.hs4j.network.core.WriteMessage; import com.google.code.hs4j.network.nio.NioSessionConfig; import com.google.code.hs4j.network.nio.impl.NioTCPSession; import com.google.code.hs4j.network.util.LinkedTransferQueue; import com.google.code.hs4j.network.util.SystemUtils; /** * HandlerSokcetSession implementation * * @author dennis */ public class HandlerSocketSessionImpl extends NioTCPSession implements HandlerSocketSession { /** * Command which are already sent */ protected BlockingQueue<Command> commandAlreadySent; private final AtomicReference<Command> currentCommand = new AtomicReference<Command>(); private SocketAddress remoteSocketAddress; // prevent channel is closed private volatile boolean allowReconnect = true; public HandlerSocketSessionImpl(NioSessionConfig sessionConfig, int readRecvBufferSize, int readThreadCount, CommandFactory commandFactory) { super(sessionConfig, readRecvBufferSize); this.commandAlreadySent = new LinkedTransferQueue<Command>(); } @Override public String toString() { return SystemUtils.getRawAddress(this.getRemoteSocketAddress()) + ":" + this.getRemoteSocketAddress().getPort(); } /* * (non-Javadoc) * * @see com.google.code.hs4j.network.hs.HandlerSocket#destroy() */ public void destroy() { Command command = this.currentCommand.get(); if (command != null) { command.setExceptionMessage("Connection has been closed"); command.countDown(); } while ((command = this.commandAlreadySent.poll()) != null) { command.setExceptionMessage("Connection has been closed"); command.countDown(); } } @Override public InetSocketAddress getRemoteSocketAddress() { InetSocketAddress result = super.getRemoteSocketAddress(); if (result == null && this.remoteSocketAddress != null) { result = (InetSocketAddress) this.remoteSocketAddress; } return result; } @Override protected final WriteMessage wrapMessage(Object msg, Future<Boolean> writeFuture) { ((Command) msg).encode(); ((Command) msg).setWriteFuture(writeFuture); if (log.isDebugEnabled()) { log.debug("After encoding" + ((Command) msg).toString()); } return super.wrapMessage(msg, writeFuture); } /** * get current command from queue * * @return */ private final Command takeExecutingCommand() { try { return this.commandAlreadySent.take(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return null; } /* * (non-Javadoc) * * @see com.google.code.hs4j.network.hs.HandlerSocket#isAllowReconnect() */ public boolean isAllowReconnect() { return this.allowReconnect; } /* * (non-Javadoc) * * @see * com.google.code.hs4j.network.hs.HandlerSocket#setAllowReconnect(boolean) */ public void setAllowReconnect(boolean reconnected) { this.allowReconnect = reconnected; } /* * (non-Javadoc) * * @see * com.google.code.hs4j.network.hs.HandlerSocket#addCommand(com.google.code * .hs4j.Command) */ public final void addCommand(Command command) { this.commandAlreadySent.add(command); } /* * (non-Javadoc) * * @see * com.google.code.hs4j.network.hs.HandlerSocket#setCurrentCommand(com.google * .code.hs4j.Command) */ public final void setCurrentCommand(Command cmd) { this.currentCommand.set(cmd); } /* * (non-Javadoc) * * @see com.google.code.hs4j.network.hs.HandlerSocket#getCurrentCommand() */ public final Command getCurrentCommand() { return this.currentCommand.get(); } /* * (non-Javadoc) * * @see com.google.code.hs4j.network.hs.HandlerSocket#takeCurrentCommand() */ public final void takeCurrentCommand() { this.setCurrentCommand(this.takeExecutingCommand()); } }