示例#1
0
  protected Object decode(Channel channel, ChannelBuffer buffer, int readable, byte[] header)
      throws IOException {
    // check magic number.
    if (readable > 0 && header[0] != MAGIC_HIGH || readable > 1 && header[1] != MAGIC_LOW) {
      int length = header.length;
      if (header.length < readable) {
        header = Bytes.copyOf(header, readable);
        buffer.readBytes(header, length, readable - length);
      }
      for (int i = 1; i < header.length - 1; i++) {
        if (header[i] == MAGIC_HIGH && header[i + 1] == MAGIC_LOW) {
          buffer.readerIndex(buffer.readerIndex() - header.length + i);
          header = Bytes.copyOf(header, i);
          break;
        }
      }
      return super.decode(channel, buffer, readable, header);
    }
    // check length.
    if (readable < HEADER_LENGTH) {
      return DecodeResult.NEED_MORE_INPUT;
    }

    // get data length.
    int len = Bytes.bytes2int(header, 12);
    checkPayload(channel, len);

    int tt = len + HEADER_LENGTH;
    if (readable < tt) {
      return DecodeResult.NEED_MORE_INPUT;
    }

    // limit input stream.
    ChannelBufferInputStream is = new ChannelBufferInputStream(buffer, len);

    try {
      return decodeBody(channel, is, header);
    } finally {
      if (is.available() > 0) {
        try {
          if (logger.isWarnEnabled()) {
            logger.warn("Skip input stream " + is.available());
          }
          StreamUtils.skipUnusedStream(is);
        } catch (IOException e) {
          logger.warn(e.getMessage(), e);
        }
      }
    }
  }
    @Override
    public void channelRead0(ChannelHandlerContext ctx, ByteBuf input) throws Exception {

      int readable = input.readableBytes();
      if (readable <= 0) {
        return;
      }

      com.alibaba.dubbo.remoting.buffer.ChannelBuffer message;
      if (buffer.readable()) {
        if (buffer instanceof DynamicChannelBuffer) {
          buffer.writeBytes(input.nioBuffer());
          message = buffer;
        } else {
          int size = buffer.readableBytes() + input.readableBytes();
          message =
              com.alibaba.dubbo.remoting.buffer.ChannelBuffers.dynamicBuffer(
                  size > bufferSize ? size : bufferSize);
          message.writeBytes(buffer, buffer.readableBytes());
          message.writeBytes(input.nioBuffer());
        }
      } else {
        message = com.alibaba.dubbo.remoting.buffer.ChannelBuffers.wrappedBuffer(input.nioBuffer());
      }

      NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);
      Object msg;
      int saveReaderIndex;

      try {
        // decode object.
        do {
          saveReaderIndex = message.readerIndex();
          try {
            msg = codec.decode(channel, message);
          } catch (IOException e) {
            buffer = com.alibaba.dubbo.remoting.buffer.ChannelBuffers.EMPTY_BUFFER;
            throw e;
          }
          if (msg == Codec2.DecodeResult.NEED_MORE_INPUT) {
            message.readerIndex(saveReaderIndex);
            break;
          } else {
            if (saveReaderIndex == message.readerIndex()) {
              buffer = com.alibaba.dubbo.remoting.buffer.ChannelBuffers.EMPTY_BUFFER;
              throw new IOException("Decode without read data.");
            }
            if (msg != null) {
              ctx.fireChannelRead(msg);
            }
          }
        } while (message.readable());
      } finally {
        if (message.readable()) {
          message.discardReadBytes();
          buffer = message;
        } else {
          buffer = com.alibaba.dubbo.remoting.buffer.ChannelBuffers.EMPTY_BUFFER;
        }
        NettyChannel.removeChannelIfDisconnected(ctx.channel());
      }
    }