Java tutorial
/* * Copyright 2008-2009 the original (zyc@hasor.net). * * 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 net.hasor.rsf.remoting.transport.netty; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import java.io.IOException; import net.hasor.rsf.constants.ProtocolStatus; import net.hasor.rsf.constants.ProtocolType; import net.hasor.rsf.remoting.transport.protocol.block.RequestSocketBlock; import net.hasor.rsf.remoting.transport.protocol.block.ResponseSocketBlock; import net.hasor.rsf.remoting.transport.protocol.codec.Protocol; import net.hasor.rsf.remoting.transport.protocol.message.RequestMsg; import net.hasor.rsf.remoting.transport.protocol.message.ResponseMsg; import net.hasor.rsf.utils.ProtocolUtils; import net.hasor.rsf.utils.TransferUtils; /** * ? * @version : 20141010 * @author (zyc@hasor.net) */ public class RSFProtocolDecoder extends LengthFieldBasedFrameDecoder { public RSFProtocolDecoder() { this(Integer.MAX_VALUE); } public RSFProtocolDecoder(int maxBodyLength) { // lengthFieldOffset = 10 // lengthFieldLength = 3 // lengthAdjustment = 0 // initialBytesToStrip = 0 super(maxBodyLength, 10, 3, 0, 0); } // /*?*/ protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { ByteBuf frame = (ByteBuf) super.decode(ctx, in); if (frame == null) { return null; } // //* byte[1] version RSF(0xC1) byte version = frame.getByte(0); short status = 0; //decode try { status = this.doDecode(version, ctx, frame);//??? } catch (Throwable e) { status = ProtocolStatus.ProtocolError; } finally { if (status == ProtocolStatus.OK) return null; /* */ frame = frame.resetReaderIndex().skipBytes(1); this.fireProtocolError(ctx, version, frame.readLong(), ProtocolStatus.ProtocolError); } return null; } protected ByteBuf extractFrame(ChannelHandlerContext ctx, ByteBuf buffer, int index, int length) { return buffer.slice(index, length); } // /**???*/ private short doDecode(byte version, ChannelHandlerContext ctx, ByteBuf frame) throws IOException { ProtocolType pType = ProtocolType.valueOf(version); if (pType == ProtocolType.Request) { //request Protocol<RequestSocketBlock> requestProtocol = ProtocolUtils.requestProtocol(version); if (requestProtocol != null) { RequestSocketBlock block = requestProtocol.decode(frame); RequestMsg reqMetaData = TransferUtils.requestToMessage(block); ctx.fireChannelRead(reqMetaData); return ProtocolStatus.OK;/*??*/ } } if (pType == ProtocolType.Response) { //response Protocol<ResponseSocketBlock> responseProtocol = ProtocolUtils.responseProtocol(version); if (responseProtocol != null) { ResponseSocketBlock block = responseProtocol.decode(frame); ResponseMsg resMetaData = TransferUtils.responseToMessage(block); ctx.fireChannelRead(resMetaData); return ProtocolStatus.OK;/*??*/ } } return ProtocolStatus.ProtocolError; } // /**?? */ private void fireProtocolError(ChannelHandlerContext ctx, byte oriVersion, long requestID, short status) { byte version = ProtocolUtils.getVersion(oriVersion); ResponseMsg error = TransferUtils.buildStatus(// version, requestID, status, "BlackHole", null); ctx.pipeline().writeAndFlush(error); } }