package com.jds.nio; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.nio.ByteOrder; import java.nio.channels.ReadableByteChannel; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; import java.nio.channels.WritableByteChannel; import java.util.ArrayDeque; import java.util.Deque; import java.util.HashMap; import java.util.Map; import com.jds.nio.buffer.NioBuffer; import com.jds.nio.core.CloseType; import com.jds.nio.core.NioService; /** * Author: VISTALL * Company: J Develop Station * Date: 02.09.2009 * Time: 18:03:20 */ public class NioSession { protected NioService _service; protected final SelectionKey _key; protected final SocketChannel _channel; protected final Socket _socket; protected final ReadableByteChannel _readByteChannel; protected final WritableByteChannel _writeByteChannel; protected boolean _pendingClose; protected CloseType _closeType; protected boolean _isClosing; public NioBuffer READ_BUFFER; public NioBuffer WRITE_BUFFER; protected final Deque<NioBuffer> _sendQueue = new ArrayDeque<NioBuffer>(); protected final Map<String, Object> _attributes = new HashMap<String, Object>(); public NioSession(SocketChannel channel, Socket socket, NioService service) throws Exception { _channel = channel; _socket = socket; _readByteChannel = socket.getChannel(); _writeByteChannel = socket.getChannel(); _service = service; _key = _channel.register(_service.getSelector(), SelectionKey.OP_READ); _key.attach(this); READ_BUFFER = NioBuffer.allocate(1024 * 16); READ_BUFFER.order(ByteOrder.LITTLE_ENDIAN); WRITE_BUFFER = NioBuffer.allocate(1024 * 16); WRITE_BUFFER.flip(); WRITE_BUFFER.order(ByteOrder.LITTLE_ENDIAN); } public int read(final NioBuffer buf) throws Exception { return _readByteChannel.read(buf.buf()); } public int write(final NioBuffer buf) throws Exception { return _writeByteChannel.write(buf.buf()); } public CloseType getCloseType() { return _closeType; } public void setCloseType(CloseType s) { _closeType = s; } public boolean isClosing() { return _isClosing; } public void setClosing(boolean s) { _isClosing = s; } public final void put(NioBuffer buff) { NioBuffer buf = _service.getProtocol().encode(this, buff); if (buf.hasRemaining()) { synchronized (_sendQueue) { if (!isWriteDisabled()) { _sendQueue.addLast(buf); } } enableWriteInterest(); } } protected void enableWriteInterest() { if (_key.isValid()) { _key.interestOps(_key.interestOps() | SelectionKey.OP_WRITE); _key.selector().wakeup(); } } public NioBuffer getNextMessage() { return _sendQueue.pollFirst(); } protected final boolean isWriteDisabled() { return _pendingClose || _isClosing; } public void close() { //_sendQueue.clear(); _service.getProcessor().close(this, CloseType.NORMAL); } public void clear() throws IOException { _socket.close(); _channel.close(); _readByteChannel.close(); _writeByteChannel.close(); } public SelectionKey getSelectionKey() { return _key; } public Socket getSocket() { return _socket; } public void setAttribute(String name, Object att) { _attributes.put(name, att); } public Object getAttribute(String name) { return _attributes.get(name); } public InetAddress getAddress() { return _socket.getInetAddress(); } public long getId() { return this.hashCode(); } }