2014-04-07 42 views
0

我在使用HexDumpProxy時遇到了一些問題。我使用netty lib netty-all-5.0.0.Alpha1.jar。Netty 5 HexDumpProxy問題

HexDumpProxyInitializer類的initChannel方法,我有

@Override 
public void initChannel(SocketChannel ch) throws Exception {   
    ChannelPipeline cp = ch.pipeline();   
    cp.addLast(new LoggingHandler(LogLevel.INFO));  
    cp.addLast("decoder", new StringDecoder()); 
    cp.addLast("encoder", new StringEncoder());   
    cp.addLast(new HexDumpProxyFrontendHandler(remoteHost, remotePort)); 
} 

HexDumpProxyFrontendHandler類,我要處理的傳入消息如下, 我在這裏轉換Object msgString和要更改的值,並在發送修改字符串時遇到問題。

@Override 
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception { 
    String s1 = ((ByteBuf) msg).toString(Charset.defaultCharset()); 
    if (outboundChannel.isActive()) { 
     outboundChannel.writeAndFlush(s1).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(); 
       } 
      } 
     }); 
    } 
} 

如果我發送對象本身沒有任何修改,它的工作正常。但是如果我想發送String,它不會拋出任何異常,也不起作用。

之後,我已經啓用String編碼器和解碼器initChannel方法,然後我收到以下錯誤,

Proxying *:9999 to 192.168.1.27:8554 ... 
java.lang.ClassCastException: java.lang.String cannot be cast to io.netty.buffer.ByteBuf 
    at ivz.proxy.HexDumpProxyFrontendHandler.channelRead(HexDumpProxyFrontendHandler.java:68) 
    at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:74) 
    at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:138) 
    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:320) 
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) 
    at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:74) 
    at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:138) 
    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:320) 
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846) 
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:127) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452) 
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346) 
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:794) 
    at java.lang.Thread.run(Unknown Source) 

除了上述方法,我還沒有在代碼改變任何東西。所以,我的問題是,我想在發送到服務器之前更改Object msg中的某些值,如何才能執行此操作?換句話說,是否可以在writeAndFlush方法中發送String

回答

0

我沒有落後outboundChannel部分的邏輯,但我認爲有幾個問題與您的代碼

cp.addLast(new LoggingHandler(LogLevel.INFO));  
cp.addLast("decoder", new StringDecoder()); 
cp.addLast("encoder", new StringEncoder());   
cp.addLast(new HexDumpProxyFrontendHandler(remoteHost, remotePort)); 
  1. 既然你HexDumpProxyFrontendHandler之前有StringDecoder,所以在channelRead對象將收到總是字符串,

    當你寫回String對象時,它將被StringEncoder編碼爲ByteBuff。

  2. 在ChannelFutureListener實現,無需調用ctx.channel().read()

    Netty中會自動調用處理的channelRead()方法

更新

通道()讀取()是必需的如果要限制/控制讀取操作,要在通道選項中設置自動讀取false,默認情況下自動讀取爲true。

+0

感謝您的短信Jestan Nirojan。首先,在這裏提出問題之前,我只是試圖將該對象轉換爲String,並希望看看我是否可以寫入,之後我正在考慮更改字符串併發送它。 1>現在我清楚地瞭解了這個過程。我用這個來測試Livets服務器和vlc作爲客戶端的Rtsp。 – user1241903

+0

如果我刪除管線conf中的解碼器/編碼器,HDProxy可以正常工作,但正如我所提到的,我想要改變請求中的某個值,所以我想使用解碼器/編碼器,但HDProxy在更改後不會拋出任何錯誤告訴,但它不工作。請幫我解決這個問題。 – user1241903

+0

2>我從netty5例子中拿了這個項目。所以我沒有意識到之前爲什麼寫了這個** ctx.channel()。read()**。 – user1241903

0

現在已經很晚了,但我也爲此付出了努力。
所以這裏是我如何解決它爲我的情況。
HexDumpProxyFrontendHandler類我做了如下修改channelActive()

@Override 
public void channelActive(ChannelHandlerContext ctx) { 
    final Channel inboundChannel = ctx.channel(); 
    // Start the connection attempt. 
    Bootstrap b = new Bootstrap(); 
    b.group(inboundChannel.eventLoop()).channel(ctx.channel().getClass()) 
      .handler(new HexDumpProxyBackendHandler(inboundChannel)) 
      .option(ChannelOption.AUTO_READ, false); 
    ChannelFuture f = b.connect(remoteHost, remotePort); 
    outboundChannel = f.channel(); 
    outboundChannel.pipeline().addFirst(new StringDecoder()); // this 2 lines 
    outboundChannel.pipeline().addFirst(new StringEncoder()); 
    f.addListener(new ChannelFutureListener() { 

     public void operationComplete(ChannelFuture future) { 
      if (future.isSuccess()) { 
       // connection complete start to read first data 
       inboundChannel.read(); 
      } else { 
       // Close the connection if the connection attempt has 
       // failed. 
       inboundChannel.close(); 
      } 
     } 
    }); 
} 

所以在這之後,在channelRead回調(用於HexDumpProxyFrontendHandler和HexDumpProxyBackendHandler),消息將String