I am facing some problem in HexDumpProxy
usage. I am using netty lib netty-all-5.0.0.Alpha1.jar.
In HexDumpProxyInitializer
class's initChannel
method, I am having
@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));
}
and in HexDumpProxyFrontendHandler
class, I want to process the incoming message as follows, here I am converting Object msg
to String
and want to change the value, and facing problem in sending modified string.
@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();
}
}
});
}
}
If I am sending object itself without any modification, its working fine. But if I want to send String
, its not throwing any exception, also not working.
After that I have enabled String
encoder and decoder in initChannel
method, then I am getting the following error,
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)
Except the above mentioned methods, I have not changed anything in the code. So, my problem is, I want to change some values in Object msg
before sending to server, How can I achive this? Or in other words, is it possible to send String
in writeAndFlush
method?
I didn't get the logic behind outboundChannel part, but I think there are couple of issues with your code
cp.addLast(new LoggingHandler(LogLevel.INFO));
cp.addLast("decoder", new StringDecoder());
cp.addLast("encoder", new StringEncoder());
cp.addLast(new HexDumpProxyFrontendHandler(remoteHost, remotePort));
Since you have StringDecoder
before HexDumpProxyFrontendHandler, so object received in the channelRead will be always String,
When you write the String object back, it will be encoded to ByteBuff by StringEncoder.
In ChannelFutureListener implementation, no need to call ctx.channel().read()
Netty will automatically call your handler's channelRead()
method
Update :
channel().read() is required if you want to throttle/control the reads, to do that you have set auto read false in channel options, by default auto read is true.
It's quite late, but I also struggled with this.
So here is how I solved it for my case.
In the HexDumpProxyFrontendHandler
class I made the following changes to 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();
}
}
});
}
So after that, in the channelRead
callbacks (for HexDumpProxyFrontendHandler and HexDumpProxyBackendHandler), the messages will be String
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.