package org.voovan.network.aio; import org.voovan.network.EventTrigger; import org.voovan.network.MessageLoader; import org.voovan.tools.ByteBufferChannel; import java.io.IOException; import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousCloseException; import java.nio.channels.ClosedChannelException; import java.nio.channels.CompletionHandler; /** * Aio 读取事件 * * @author helyho * * Voovan Framework. * WebSite: https://github.com/helyho/Voovan * Licence: Apache v2 License */ public class ReadCompletionHandler implements CompletionHandler<Integer, ByteBuffer>{ private AioSocket aioSocket; private ByteBufferChannel netByteBufferChannel; private ByteBufferChannel appByteBufferChannel; private AioSession session; private Method readSSLMethod; public ReadCompletionHandler(AioSocket aioSocket, ByteBufferChannel byteBufferChannel){ this.aioSocket = aioSocket; this.appByteBufferChannel = byteBufferChannel; this.session = aioSocket.getSession(); netByteBufferChannel = new ByteBufferChannel(session.socketContext().getBufferSize()); } @Override public void completed(Integer length, ByteBuffer buffer) { try { // 如果对端连接关闭,或者 session 关闭,则直接调用 session 的关闭 if (MessageLoader.isRemoteClosed(buffer, length) && session.isConnected()) { session.getMessageLoader().setStopType(MessageLoader.StopType.STREAM_END); //如果 Socket 流达到结尾,则关闭连接 while(session.isConnected()) { if (session.getByteBufferChannel().size() == 0) { session.close(); } } } else { buffer.flip(); if (length > 0) { // 接收数据 if(session.getSSLParser()!=null && session.getSSLParser().isHandShakeDone()){ netByteBufferChannel.writeEnd(buffer); session.getSSLParser().unWarpByteBufferChannel(session, netByteBufferChannel, appByteBufferChannel); }else{ appByteBufferChannel.writeEnd(buffer); } // 触发 onReceive 事件 EventTrigger.fireReceiveThread(session); // 接收完成后重置buffer对象 buffer.clear(); // 继续接收 Read 请求 if(aioSocket.isConnected()) { aioSocket.catchRead(buffer); } } } } catch (IOException e) { // 触发 onException 事件 session.getMessageLoader().setStopType(MessageLoader.StopType.EXCEPTION); EventTrigger.fireExceptionThread(session, e); } } @Override public void failed(Throwable exc, ByteBuffer buffer) { if((exc instanceof AsynchronousCloseException) || (exc instanceof ClosedChannelException)){ return; } if(exc instanceof Exception){ //触发 onException 事件 EventTrigger.fireExceptionThread(session, (Exception)exc); } } public void release(){ netByteBufferChannel.release(); } }