package com.jds.nio; import java.io.IOException; import java.nio.ByteOrder; import java.nio.channels.SelectionKey; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; 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:47:26 */ public class NioProcessor { private NioService _service; private final Queue<NioSession> _pendingClose; public NioProcessor(NioService service) { _service = service; _pendingClose = new ConcurrentLinkedQueue<NioSession>(); } public void accept(SelectionKey key) { SocketChannel sc; try { while ((sc = ((ServerSocketChannel) key.channel()).accept()) != null) { sc.configureBlocking(false); NioSession nioSession = new NioSession(sc, sc.socket(), _service); _service.fireSessionCreate(nioSession); } } catch (Exception e) { //_service.fireCatchException(e); } } public void read(SelectionKey key) { NioSession nioSession = (NioSession) key.attachment(); if (nioSession.getSocket().isClosed()) { return; } try { NioBuffer buf = nioSession.READ_BUFFER; int readBytes = 0; try { readBytes = nioSession.read(buf); } finally { buf.flip(); } if (readBytes == -1) { close(nioSession, CloseType.NORMAL); } if (readBytes == -2) { close(nioSession, CloseType.FORCE); } if (readBytes == 0) { return; } int pos = buf.position(); byte[] at = new byte[buf.remaining()]; buf.get(at); buf.position(pos); //System.out.println("In: " + Util.printData(at)); NioBuffer buff0 = NioBuffer.wrap(at).order(ByteOrder.LITTLE_ENDIAN).position(0); _service.fireReceiveBuffer(nioSession, buff0); if (buf.hasRemaining()) { nioSession.READ_BUFFER.compact(); } else { buf.clear(); } } catch (Exception e) { if (e instanceof IOException) { close(nioSession, CloseType.FORCE); } _service.fireCatchException(e); } } public void write(SelectionKey key) { NioSession nioSession = (NioSession) key.attachment(); NioBuffer buf = nioSession.WRITE_BUFFER; int writeBytes = 0; try { if (buf.hasRemaining()) { writeBytes = nioSession.write(buf); if (writeBytes == 0) { return; } if (buf.hasRemaining()) { return; } } while (true) { buf.clear(); NioBuffer buf2 = nioSession.getNextMessage(); if (buf2 == null) { buf.limit(0); break; } buf.put(buf2); buf.flip(); writeBytes = nioSession.write(buf); if (writeBytes == 0) { return; } if (buf.hasRemaining()) { return; } } key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); } catch (Exception e) { if (e instanceof IOException) { close(nioSession, CloseType.FORCE); } _service.fireCatchException(e); } } public Queue<NioSession> pendingClose() { return _pendingClose; } public void close(NioSession session, CloseType type) { if (session.isClosing()) { return; } session.setCloseType(type); session.setClosing(true); synchronized (_pendingClose) { _pendingClose.add(session); } } }