简体   繁体   English

Netty 4.0-将数据发送到不同事件循环上的通道

[英]Netty 4.0 - Sending data to channels on different eventloops

I'm not sure how to do this and I think my approach is wrong - Could someone please give me a hint? 我不确定该怎么做,我认为我的方法是错误的-有人可以给我提示吗?

I have made a proxy server very similar to the example HexDumpProxy . 我已经使代理服务器与示例HexDumpProxy非常相似。 The purpose is not to dump traffic but to manipulate the data parsing through the proxy and this part works perfectly. 目的不是转储流量,而是通过代理来操纵数据解析,此部分可以完美地工作。 Lets call this the proxy part. 让我们称其为代理部分。

In the same program I start up a second thread listening on another port using another ServerBootstrap and this has it's own eventloop etc. When I receive something on this listening port I would like to send this data to one of channels of the proxy part and I want to be to change this channel dynamically. 在同一程序中,我启动了另一个线程,使用另一个ServerBootstrap在另一个端口上侦听,并且它具有自己的eventloop等。当我在此侦听端口上收到消息时,我想将此数据发送到代理部分的一个通道,我想成为动态更改此频道。 When I send data to one of the proxy channels I get this error: 当我将数据发送到代理通道之一时,出现此错误:

Apr 29, 2013 10:05:10 PM BackendListenHandler exceptionCaught WARNING: Unexpected exception from downstream. 2013年4月29日,下午10:05:10 BackendListenHandler exceptionCaught警告:​​下游出现意外异常。 java.lang.IllegalStateException: nextOutboundByteBuffer() called from outside the eventLoop java.lang.IllegalStateException:从eventLoop外部调用nextOutboundByteBuffer()

@Sharable
public class BackendListenHandler extends ChannelInboundByteHandlerAdapter {

private Channel outboundChannel;

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    ctx.read();
    ctx.flush();
}

@Override
public void inboundBufferUpdated(final ChannelHandlerContext ctx, ByteBuf in) throws Exception {

    outboundChannel = Proxy.connectionTable.frontendListenChannel;

    if (!outboundChannel.isActive()) {
        System.out.println("channel id=" + outboundChannel.id() + " is NOT active...");
    } else if (outboundChannel.isActive()) {
        ByteBuf out = outboundChannel.outboundByteBuffer();
        out.writeBytes(in);
        outboundChannel.flush().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 channelInactive(ChannelHandlerContext ctx) throws Exception {
    if (outboundChannel != null) {
        closeOnFlush(outboundChannel);
    }
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    logger.log(
        Level.WARNING,
        "Unexpected exception from downstream.", cause);
    ctx.close();
}

static void closeOnFlush(Channel ch) {
    if (ch.isActive()) {
        ch.flush().addListener(ChannelFutureListener.CLOSE);
    }
}
}

For testing I keep and change my proxy Channels in this static variable: 为了进行测试,我在此静态变量中保留并更改了我的代理通道:

Proxy.connectionTable.frontendListenChannel;

Use the same EventLoop when create the Bootstrap for the "outbound" connection like shown in the HexDump example. 为“出站”连接创建Bootstrap时,请使用相同的EventLoop,如HexDump示例中所示。 This will ensure everything is handled from the same IO threads. 这将确保所有内容均由相同的IO线程处理。 See [1]. 参见[1]。

[1] https://github.com/netty/netty/blob/master/example/src/main/java/io/netty/example/proxy/HexDumpProxyFrontendHandler.java#L46 [1] https://github.com/netty/netty/blob/master/example/src/main/java/io/netty/example/proxy/HexDumpProxyFrontendHandler.java#L46

Instead of using "outboundChannel.outboundByteBuffer()" - I used "Unpooled.copiedBuffer()" to write bytes to channel from another EventLoop. 我没有使用“ outboundChannel.outboundByteBuffer()”,而是使用了“ Unpooled.copiedBuffer()”将字节从另一个EventLoop写入通道。

@Override
public void inboundBufferUpdated(final ChannelHandlerContext ctx, ByteBuf in) throws   Exception {
outboundChannel = null;
if (Proxy.connectionTable.channelId != 0) {
    outboundChannel = Proxy.allChannels.find(Proxy.connectionTable.channelId);
    if (outboundChannel.isActive()) {               
        System.out.println("NOTIFY channel id=" + outboundChannel.id() + " is active...");
        Rewrite rewrite = new Rewrite(byteBufConverter.byteBufToString(in), 2);
        in.clear();
        in = byteBufConverter.stringToByteBuf(rewrite.getFixedMessage());   
        outboundChannel.write(in);
        outboundChannel.flush().addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    ctx.channel().read();
                } else {
                    future.channel().close();
                }
            }
        });
    }
}
}

Where "byteBufConverter.stringToByteBuf(rewrite.getFixedMessage())" returns "Unpooled.copiedBuffer(strFixed.getBytes())" 其中“ byteBufConverter.stringToByteBuf(rewrite.getFixedMessage())”返回“ Unpooled.copiedBuffer(strFixed.getBytes())”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM