@Override
 public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
   if (msg instanceof ByteBuf) {
     // handle normal request
     final ByteBuf chunk = (ByteBuf) msg;
     if (flushedBuffer) {
       bufferedMode = false;
     }
     if (bufferedMode) {
       try {
         channelBuffer.writeBytes(chunk);
         ctx.channel().read();
       } catch (IndexOutOfBoundsException iobe) {
         logger.trace(
             "Flushing buffer upstream and switching to chunked mode as downstream response too large");
         bufferedMode = false;
         // write and flush buffer upstream
         if (outboundChannel.isActive()) {
           outboundChannel
               .writeAndFlush(channelBuffer)
               .addListener(
                   new ChannelFutureListener() {
                     @Override
                     public void operationComplete(ChannelFuture future) throws Exception {
                       if (future.isSuccess()) {
                         // write and flush this chunk upstream in case this single chunk is too
                         // large for buffer
                         channelRead(ctx, chunk);
                       } else {
                         future.channel().close();
                       }
                     }
                   });
         }
       }
     } else {
       bufferedMode = false;
       if (outboundChannel.isActive()) {
         outboundChannel
             .writeAndFlush(chunk)
             .addListener(
                 new ChannelFutureListener() {
                   @Override
                   public void operationComplete(ChannelFuture future) throws Exception {
                     if (future.isSuccess()) {
                       // was able to flush out data, start to read the next chunk
                       ctx.channel().read();
                     } else {
                       future.channel().close();
                     }
                   }
                 });
       }
     }
   }
 }
예제 #2
0
  public void onMessage(Message message) {
    if (message.getType() == MessageType.MSG && message.get(MessageProperty.ROOM).equals("#main")) {
      long userId = message.get(MessageProperty.USER_ID);
      String name = message.get(MessageProperty.NAME);
      UserCredentials userCredentials = null;
      if (needsFetchingConnectionData(userId)) {
        userCredentials = fetchConnectionDataForUser(name, userId);
      }

      if (userCredentials != null) {
        String id = userCredentials.getId();
        Channel channel = connections.get(id.toLowerCase());
        if (channel == null || !channel.isActive()) {
          try {
            channel = createConnection(id, userCredentials.getToken());
          } catch (InterruptedException e) {
            logger.warn("", e);
          }
        }
        if (channel != null) {
          channel.attr(lastMessageAttrKey).set(System.currentTimeMillis());
          channel.writeAndFlush(
              "PRIVMSG #" + this.channel + " :" + message.get(MessageProperty.TEXT) + "\r\n");
        }
      }
    }
  }
 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
   cause.printStackTrace();
   Channel ch = ctx.channel();
   if (ch.isActive()) {
     ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
   }
 }
  public void channelRead(final ChannelHandlerContext remoteChannelCtx, final Object msg)
      throws Exception {
    LoggerUtil.debug(
        logger, uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY), "Remote msg", msg);

    remainMsgCount++;

    if (remainMsgCount <= 5) {
      remoteChannelCtx.read();
    }

    HttpObject ho = (HttpObject) msg;

    if (ho instanceof HttpResponse) {
      HttpResponse httpResponse = (HttpResponse) ho;

      LoggerUtil.info(
          forwardRestLogger,
          uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY),
          httpResponse.getStatus(),
          httpResponse.getProtocolVersion());

      httpResponse.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
      httpResponse.headers().set("Proxy-Connection", HttpHeaders.Values.KEEP_ALIVE);
    }

    if (uaChannel.isActive()) {
      uaChannel
          .writeAndFlush(ho)
          .addListener(
              new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                  LoggerUtil.debug(
                      logger,
                      uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY),
                      "Write to UA finished: " + future.isSuccess());
                  if (future.isSuccess()) {
                    remainMsgCount--;
                    remoteChannelCtx.read();
                    LoggerUtil.debug(
                        logger,
                        uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY),
                        "Fire read again");
                  } else {
                    remoteChannelCtx.close();
                  }
                }
              });
    } else {
      remoteChannelCtx.close();
    }
  }
 @Override
 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
   if (bufferedMode && outboundChannel.isActive()) {
     flushedBuffer = true;
     outboundChannel
         .writeAndFlush(interceptor.intercept(ctx, channelBuffer, logger))
         .addListener(
             new ChannelFutureListener() {
               @Override
               public void operationComplete(ChannelFuture future) throws Exception {
                 if (future.isSuccess()) {
                   channelBuffer.clear();
                 } else {
                   future.channel().close();
                 }
               }
             });
   }
   super.channelReadComplete(ctx);
 }
예제 #6
0
 @Override
 public void run() {
   try {
     logger.debug("starting cleanup");
     for (Map.Entry<String, Channel> entry : connections.entrySet()) {
       Channel channel = entry.getValue();
       Long lastMessage = channel.attr(lastMessageAttrKey).get();
       if (System.currentTimeMillis() - lastMessage > FIVE_MINUTES) {
         channel.disconnect();
         connections.remove(entry.getKey());
         logger.debug("connection released for {}", entry.getKey());
       } else if (!channel.isActive()) {
         connections.remove(entry.getKey());
         logger.debug("connection released for {}", entry.getKey());
       }
     }
     logger.debug("cleanup complete");
   } catch (Exception e) {
     logger.error("exception while clean up", e);
   }
 }
 @Override
 public void channelInactive(ChannelHandlerContext ctx) throws Exception {
   if (outboundChannel.isActive()) {
     outboundChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
   }
 }