本文介绍了每个UDP数据报的Netty不同管道的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经有一个已经在TCP / IP中实现的服务器,但我们现在也要求协议支持UDP。

We've got a server which is already implemented in TCP/IP but we now have a requirement for the protocol to support UDP as well.

每个UDP数据报发送包含我需要解码的所有内容,因此它是一个非常简单的回复和响应系统,数据报中的数据由换行符分隔。

Each UDP datagram sent contains everything I need to decode so it is a very simple reply and response system with data in the datagram separated by line breaks.

启动服务器时引导程序的代码如下所示:

The code for the bootstrap when the server is started is shown below:

    //SETUP UDP SERVER
    DatagramChannelFactory udpFactory = new NioDatagramChannelFactory(Executors.newCachedThreadPool());

    ConnectionlessBootstrap udpBootstrap = new ConnectionlessBootstrap(udpFactory);

    udpBootstrap.setOption("sendBufferSize", 65536);
    udpBootstrap.setOption("receiveBufferSize", 65536);
    udpBootstrap.setOption("receiveBufferSizePredictorFactory", new AdaptiveReceiveBufferSizePredictorFactory());

    udpBootstrap.setOption("broadcast", "true");
    udpBootstrap.setPipelineFactory(new ServerPipeLineFactoryUDP());
    udpBootstrap.bind(new InetSocketAddress(hostIp, 4000));

管道代码是:

class ServerPipeLineFactoryUDP implements ChannelPipelineFactory
{

    private final static ExecutionHandler EXECUTION_HANDLER = new ExecutionHandler(new OrderedMemoryAwareThreadPoolExecutor(ScorpionFMS.THREAD_POOL_COUNT, 0, 0));

    public ServerPipeLineFactoryUDP()
    {

    }

    @Override
    public ChannelPipeline getPipeline() throws Exception
    {

    ChannelPipeline pipeline = pipeline();
    pipeline.addLast("debugup", new DebugUpstreamHandler("UDP"));
    pipeline.addLast("debugdown", new DebugDownstreamHandler("UDP"));

    pipeline.addLast("framer", new DelimiterBasedFrameDecoder(256, Delimiters.lineDelimiter()));

    pipeline.addLast("decoder", new UDPRequestDecoder(true));
    pipeline.addLast("encoder", new StringEncoder());
    pipeline.addLast("executor", EXECUTION_HANDLER);
    pipeline.addLast("handler", new UDPRequestHandler(

    return pipeline;
    }
}

我遇到的问题是每个数据报都在使用这个管道的同一个实例(我希望每个数据报都使用一个新的管道实例),所以所有的状态我存储,同时处理数据报的内容,并且下一个数据报也使用它(对于TCP,每个连接都有自己的通道,因此它自己的管道实例和它自己的状态)

The problem im having is each datagram is using the same instance of this pipeline (i hoped each datagram would use a new instance of the pipeline), so all the state i store while processing the contents of a datagram is saved and the next datagram uses it as well,( whereas for TCP each connection would have its own channel and therefore its own instance of the pipeline and its own state)

我知道这是阅读文档时的预期行为,但无论如何都要强制netty为每个数据报重新创建管道?或者我是否以完全错误的方式解决这个问题?

I know this is the expected behaviour from reading the documentation but is there anyway to force netty to recreate the pipeline for each datagram? Or am i going about this the completely wrong way?

简而言之,我希望每个数据报都有一个新的管道实例(与tcp相同)

To put it succinctly, i want each datagram to have a new instance of the pipeline (the same as tcp)

推荐答案

就像我在IRC中所说的那样,我认为可以做你想要的或至少给你的一些想法。

Like I said in IRC, I think that could do what you want or at least give you some idea.

public class Example {

    public static void main(String[] args) {
        final ChannelPipelineHandlerImpl perDatagramFactory = new ChannelPipelineHandlerImpl();

        DatagramChannelFactory udpFactory = new NioDatagramChannelFactory(Executors.newCachedThreadPool());

        ConnectionlessBootstrap udpBootstrap = new ConnectionlessBootstrap(udpFactory);

        udpBootstrap.setPipelineFactory(new ChannelPipelineFactory() {

            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(new DistinctChannelPipelineHandler(perDatagramFactory));
            }
        });

    }

    private static final class DistinctChannelPipelineHandler implements ChannelDownstreamHandler, ChannelUpstreamHandler {
        private ChannelPipelineFactory factory;

        public DistinctChannelPipelineHandler(ChannelPipelineFactory factory) {
            this.factory = factory;
        }

        public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
            ChannelPipeline pipeline = factory.getPipeline();
            pipeline.attach(ctx.getChannel(), ctx.getPipeline().getSink());
            pipeline.sendUpstream(e);

            ctx.sendUpstream(e);

        }

        public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
            ChannelPipeline pipeline = factory.getPipeline();
            pipeline.attach(ctx.getChannel(), ctx.getPipeline().getSink());
            pipeline.sendDownstream(e);

            ctx.sendDownstream(e);
        }

    }

    private static final class ChannelPipelineHandlerImpl implements ChannelPipelineFactory {

        public ChannelPipeline getPipeline() throws Exception {
            // Add your handlers here
            return Channels.pipeline();
        }

    }
}

这篇关于每个UDP数据报的Netty不同管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-16 21:35
查看更多