@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(); } } }); } } } }
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); }
@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); } }