コード例 #1
0
ファイル: GrizzlyCodecAdapter.java プロジェクト: yjq635/dubbo
 /*
  * 接收
  *
  * @param context 上下文
  * @param channel 通道
  * @param buffer 缓存
  * @param readable 缓存可读
  * @param bytes 输入缓存
  * @param offset 指向已读数据的偏移量,off之前的数据都是已用过的
  * @param limit 有效长度,limit之后的长度是空白或无效数据,off到limit之间的数据是准备使用的数据
  * @return 后续动作
  * @throws IOException
  */
 private NextAction receive(
     FilterChainContext context,
     Channel channel,
     Buffer buffer,
     int readable,
     byte[] bytes,
     int offset,
     int limit)
     throws IOException {
   for (; ; ) {
     int read = Math.min(readable, bytes.length - limit); // 取bytes缓存空闲区,和可读取新数据,的最小值,即:此次最多读写数据的大小
     buffer.get(bytes, limit, read); // 从可读取新数据中,读取数据,尽量填满bytes缓存空闲区
     limit += read; // 有效数据变长
     readable -= read; // 可读数据变少
     UnsafeByteArrayInputStream input =
         new UnsafeByteArrayInputStream(
             bytes, offset, limit - offset); // 将bytes缓存转成InputStream,不需要关闭
     Object msg = upstreamCodec.decode(channel, input); // 调用Codec接口,解码数据
     if (msg == Codec.NEED_MORE_INPUT) { // 如果Codec觉得数据不够,不足以解码成一个对象
       if (readable == 0) { // 如果没有更多可读数据
         channel.setAttribute(
             BUFFER_KEY, new Object[] {bytes, offset, limit}); // 放入通道属性中,等待下一个Buffer的到来
         return context.getStopAction();
       } else { // 扩充或挪出空闲区,并循环,直到可读数据都加载到bytes缓存
         if (offset == 0) { // 如果bytes缓存全部没有被使用,如果这时数据还不够
           bytes = Bytes.copyOf(bytes, bytes.length << 1); // 将bytes缓存扩大一倍
         } else { // 如果bytes缓存有一段数据已被使用
           int len = limit - offset; // 计算有效数据长度
           System.arraycopy(
               bytes, offset, bytes, 0, len); // 将数据向前移到,压缩到已使用的部分,这样limit后面就会多出一些空闲,可以放数据
           offset = 0; // 移到后,bytes缓存没有数据被使用
           limit = len; // 移到后,有效数据都在bytes缓存最前面
         }
       }
     } else { // 如果解析出一个结果
       int position = input.position(); // 记录InputStream用了多少
       if (position == offset) { // 如果InputStream没有被读过,就返回了数据,直接报错,否则InputStream永远读不完,会死递归
         throw new IOException("Decode without read data.");
       }
       offset = position; // 记录已读数据
       context.setMessage(msg); // 将消息改为解码后的对象,以便被后面的Filter使用。
       if (limit - offset > 0 || readable > 0) { // 如果有效数据没有被读完,或者Buffer区还有未读数据
         return context.getInvokeAction(
             new Object[] {
               buffer, readable, bytes, offset, limit
             }); // 正常执行完Filter,并重新发起一轮Filter,继续读
       } else { // 否则所有数据读完
         return context.getInvokeAction(); // 正常执行完Filter
       }
     }
   }
 }
コード例 #2
0
ファイル: GrizzlyCodecAdapter.java プロジェクト: yjq635/dubbo
  @Override
  public NextAction handleWrite(FilterChainContext context) throws IOException {
    Connection<?> connection = context.getConnection();
    GrizzlyChannel channel = GrizzlyChannel.getOrAddChannel(connection, url, handler);
    try {
      UnsafeByteArrayOutputStream output = new UnsafeByteArrayOutputStream(1024); // 不需要关闭

      if (!(context.getMessage() instanceof Response)) {
        downstreamCodec.encode(channel, output, context.getMessage());
      } else {
        upstreamCodec.encode(channel, output, context.getMessage());
      }

      GrizzlyChannel.removeChannelIfDisconnectd(connection);
      byte[] bytes = output.toByteArray();
      Buffer buffer = connection.getTransport().getMemoryManager().allocate(bytes.length);
      buffer.put(bytes);
      buffer.flip();
      buffer.allowBufferDispose(true);
      context.setMessage(buffer);
    } finally {
      GrizzlyChannel.removeChannelIfDisconnectd(connection);
    }
    return context.getInvokeAction();
  }
コード例 #3
0
    @Override
    public NextAction handleRead(final FilterChainContext ctx) throws IOException {

      String message = (String) ctx.getMessage();

      logger.log(Level.INFO, "First chunk come: {0}", message);
      intermResultQueue.add(message);

      Connection connection = ctx.getConnection();
      connection.setBlockingReadTimeout(10, TimeUnit.SECONDS);

      try {
        for (int i = 0; i < clientMsgs - 1; i++) {
          final ReadResult rr = ctx.read();
          final String blckMsg = (String) rr.getMessage();

          rr.recycle();
          logger.log(Level.INFO, "Blocking chunk come: {0}", blckMsg);
          intermResultQueue.add(blckMsg);
          message += blckMsg;
        }
      } catch (Exception e) {
        intermResultQueue.add(e);
        return ctx.getStopAction();
      }

      ctx.setMessage(message);

      return ctx.getInvokeAction();
    }
コード例 #4
0
  @Override
  public NextAction handleWrite(FilterChainContext ctx) throws IOException {

    try {
      Thread.sleep(random.nextInt(50) + 10);
    } catch (InterruptedException ignored) {
    }

    return ctx.getInvokeAction();
  }
コード例 #5
0
  @Override
  public NextAction handleRead(final FilterChainContext ctx) throws IOException {
    final HttpContent httpContent = ctx.getMessage();
    if (httpContent.isLast()) {
      // Perform the cleanup logic if it's the last chunk of the payload
      final HttpResponsePacket response = (HttpResponsePacket) httpContent.getHttpHeader();

      recycleRequestResponsePackets(ctx.getConnection(), response);
      return ctx.getStopAction();
    }

    return ctx.getInvokeAction();
  }
コード例 #6
0
  @Override
  public NextAction handleWrite(final FilterChainContext ctx) throws IOException {

    Object message = ctx.getMessage();
    if (message instanceof RequestInfoHolder) {
      ctx.setMessage(null);
      if (!sendAsGrizzlyRequest((RequestInfoHolder) message, ctx)) {
        return ctx.getSuspendAction();
      }
    } else if (message instanceof Buffer) {
      return ctx.getInvokeAction();
    }

    return ctx.getStopAction();
  }
コード例 #7
0
ファイル: GrizzlyCodecAdapter.java プロジェクト: yjq635/dubbo
 @Override
 public NextAction handleRead(FilterChainContext context) throws IOException {
   Object message = context.getMessage();
   Connection<?> connection = context.getConnection();
   Channel channel = GrizzlyChannel.getOrAddChannel(connection, url, handler);
   try {
     if (message instanceof Buffer) { // 收到新的数据包
       Buffer buffer = (Buffer) message; // 缓存
       int readable = buffer.capacity(); // 本次可读取新数据的大小
       if (readable == 0) {
         return context.getStopAction();
       }
       byte[] bytes; // byte[]缓存区,将Buffer转成byte[],再转成UnsafeByteArrayInputStream
       int offset; // 指向已用数据的偏移量,off之前的数据都是已用过的
       int limit; // 有效长度,limit之后的长度是空白或无效数据,off到limit之间的数据是准备使用的有效数据
       Object[] remainder = (Object[]) channel.getAttribute(BUFFER_KEY); // 上次序列化剩下的数据
       channel.removeAttribute(BUFFER_KEY);
       if (remainder == null) { // 如果没有,创建新的bytes缓存
         bytes = new byte[bufferSize];
         offset = 0;
         limit = 0;
       } else { // 如果有,使用剩下的bytes缓存
         bytes = (byte[]) remainder[0];
         offset = (Integer) remainder[1];
         limit = (Integer) remainder[2];
       }
       return receive(context, channel, buffer, readable, bytes, offset, limit);
     } else if (message instanceof Object[]) { // 同一Buffer多轮Filter,即:一个Buffer里有多个请求
       Object[] remainder = (Object[]) message;
       Buffer buffer = (Buffer) remainder[0];
       int readable = (Integer) remainder[1];
       byte[] bytes = (byte[]) remainder[2];
       int offset = (Integer) remainder[3];
       int limit = (Integer) remainder[4];
       return receive(context, channel, buffer, readable, bytes, offset, limit);
     } else { // 其它事件直接往下传
       return context.getInvokeAction();
     }
   } finally {
     GrizzlyChannel.removeChannelIfDisconnectd(connection);
   }
 }
コード例 #8
0
  /**
   * Method is called, when new client {@link Connection} was connected to some endpoint
   *
   * @param ctx the filter chain context
   * @return the next action to be executed by chain
   * @throws java.io.IOException
   */
  @Override
  public NextAction handleConnect(FilterChainContext ctx) throws IOException {
    newConnection(ctx.getConnection());

    return ctx.getInvokeAction();
  }
コード例 #9
0
 /**
  * Method is called, when the {@link Connection} is getting closed
  *
  * @param ctx the filter chain context
  * @return the next action to be executed by chain
  * @throws java.io.IOException
  */
 @Override
 public NextAction handleClose(FilterChainContext ctx) throws IOException {
   activeConnectionsMap.remove(ctx.getConnection());
   return ctx.getInvokeAction();
 }