@Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { RequestWrapper request = (RequestWrapper) msg; long beginTime = System.currentTimeMillis(); ResponseWrapper responseWrapper = ProtocolFactory.getServerHandler(request.getProtocolType()).handleRequest(request); final int id = request.getId(); // already timeout,so not return if ((System.currentTimeMillis() - beginTime) >= request.getTimeout()) { LOGGER.warn( "timeout,so give up send response to client,requestId is:" + id + ",client is:" + ctx.channel().remoteAddress() + ",consumetime is:" + (System.currentTimeMillis() - beginTime) + ",timeout is:" + request.getTimeout()); return; } ChannelFuture wf = ctx.channel().writeAndFlush(responseWrapper); wf.addListener( new ChannelFutureListener() { public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { LOGGER.error("server write response error,request id is: " + id); } } }); }
public Object decode(ByteBufferWrapper wrapper, Object errorObject, int... originPosArray) throws Exception { final int originPos; if (originPosArray != null && originPosArray.length == 1) { originPos = originPosArray[0]; } else { originPos = wrapper.readerIndex(); } if (wrapper.readableBytes() < CUSTOMPROTOCOL_HEADER_LEN) { wrapper.setReaderIndex(originPos); return errorObject; } byte version = wrapper.readByte(); if (version == (byte) 1) { byte type = wrapper.readByte(); int codecType = wrapper.readByte(); wrapper.readByte(); wrapper.readByte(); wrapper.readByte(); int requestId = wrapper.readInt(); int timeout = wrapper.readInt(); int classNameLen = wrapper.readInt(); int bodyLen = wrapper.readInt(); if (wrapper.readableBytes() < bodyLen + classNameLen) { wrapper.setReaderIndex(originPos); return errorObject; } byte[] classNameByte = null; if (codecType == Codecs.PB_CODEC) { classNameByte = new byte[classNameLen]; wrapper.readBytes(classNameByte); } byte[] body = new byte[bodyLen]; wrapper.readBytes(body); int messageLen = ProtocolUtils.HEADER_LEN + CUSTOMPROTOCOL_HEADER_LEN + classNameLen + bodyLen; if (type == REQUEST) { RequestWrapper requestWrapper = new RequestWrapper(body, timeout, requestId, codecType, TYPE); requestWrapper.setMessageLen(messageLen); requestWrapper.setArgTypes(new byte[][] {classNameByte}); return requestWrapper; } else if (type == RESPONSE) { ResponseWrapper responseWrapper = new ResponseWrapper(requestId, codecType, TYPE); responseWrapper.setResponse(body); responseWrapper.setMessageLen(messageLen); responseWrapper.setResponseClassName(classNameByte); return responseWrapper; } else { throw new UnsupportedOperationException("protocol type : " + type + " is not supported!"); } } else { throw new UnsupportedOperationException( "protocol version :" + version + " is not supported!"); } }
@SuppressWarnings("rawtypes") private void sendErrorResponse(final IoSession session, final RequestWrapper request) { ResponseWrapper responseWrapper = new ResponseWrapper(request.getId(), request.getCodecType(), request.getProtocolType()); responseWrapper.setException( new Exception("server threadpool full,maybe because server is slow or too many requests")); WriteFuture wf = session.write(responseWrapper); wf.addListener( new IoFutureListener() { public void operationComplete(IoFuture future) { if (!((WriteFuture) future).isWritten()) { LOGGER.error("server write response error,request id is: " + request.getId()); } } }); }
@SuppressWarnings("rawtypes") public void run() { // pipeline if (message instanceof List) { List messages = (List) message; for (Object messageObject : messages) { threadPool.execute(new HandlerRunnable(session, messageObject, threadPool)); } } else { RequestWrapper request = (RequestWrapper) message; long beginTime = System.currentTimeMillis(); ResponseWrapper responseWrapper = ProtocolFactory.getServerHandler(request.getProtocolType()).handleRequest(request); final int id = request.getId(); // already timeout,so not return if ((System.currentTimeMillis() - beginTime) >= request.getTimeout()) { LOGGER.warn( "timeout,so give up send response to client,requestId is:" + id + ",client is:" + session.getRemoteAddress() + ",consumetime is:" + (System.currentTimeMillis() - beginTime) + ",timeout is:" + request.getTimeout()); return; } WriteFuture wf = session.write(responseWrapper); wf.addListener( new IoFutureListener() { public void operationComplete(IoFuture future) { if (!((WriteFuture) future).isWritten()) { LOGGER.error("server write response error,request id is: " + id); } } }); } }
public ByteBufferWrapper encode(Object message, ByteBufferWrapper bytebufferWrapper) throws Exception { if (!(message instanceof RequestWrapper) && !(message instanceof ResponseWrapper)) { throw new Exception("only support send RequestWrapper && ResponseWrapper"); } int id = 0; byte type = REQUEST; byte[] body = null; int timeout = 0; int codecType = 0; byte[] className = null; if (message instanceof RequestWrapper) { try { RequestWrapper wrapper = (RequestWrapper) message; codecType = wrapper.getCodecType(); body = Codecs.getEncoder(codecType).encode(wrapper.getMessage()); id = wrapper.getId(); timeout = wrapper.getTimeout(); if (codecType == Codecs.PB_CODEC) className = wrapper.getMessage().getClass().getName().getBytes(); } catch (Exception e) { LOGGER.error("encode request object error", e); throw e; } } else { ResponseWrapper wrapper = (ResponseWrapper) message; try { codecType = wrapper.getCodecType(); body = Codecs.getEncoder(codecType).encode(wrapper.getResponse()); id = wrapper.getRequestId(); if (codecType == Codecs.PB_CODEC) className = wrapper.getResponse().getClass().getName().getBytes(); } catch (Exception e) { LOGGER.error("encode response object error", e); // still create response,so client can get it wrapper.setResponse(new Exception("encode response object error", e)); if (codecType == Codecs.PB_CODEC) className = Exception.class.getName().getBytes(); body = Codecs.getEncoder(wrapper.getCodecType()).encode(wrapper.getResponse()); } type = RESPONSE; } int capacity = ProtocolUtils.HEADER_LEN + CUSTOMPROTOCOL_HEADER_LEN + body.length; if (codecType == Codecs.PB_CODEC) { capacity += className.length; } ByteBufferWrapper byteBuffer = bytebufferWrapper.get(capacity); byteBuffer.writeByte(ProtocolUtils.CURRENT_VERSION); byteBuffer.writeByte((byte) TYPE); byteBuffer.writeByte(VERSION); byteBuffer.writeByte(type); byteBuffer.writeByte((byte) codecType); byteBuffer.writeByte((byte) 0); byteBuffer.writeByte((byte) 0); byteBuffer.writeByte((byte) 0); byteBuffer.writeInt(id); byteBuffer.writeInt(timeout); if (codecType == Codecs.PB_CODEC) { byteBuffer.writeInt(className.length); } else { byteBuffer.writeInt(0); } byteBuffer.writeInt(body.length); if (codecType == Codecs.PB_CODEC) byteBuffer.writeBytes(className); byteBuffer.writeBytes(body); return byteBuffer; }