3

TCP / IPにすでに実装されているサーバーがありますが、UDPもサポートするためのプロトコルの要件があります。

送信される各UDPデータグラムには、デコードする必要のあるすべてのものが含まれているため、データグラム内のデータが改行で区切られた非常に単純な応答および応答システムです。

サーバー起動時のブートストラップのコードを以下に示します。

    //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の場合、各接続には独自のチャネルがあり、したがってパイプラインの独自のインスタンスと独自の状態があります)

これがドキュメントを読んだときに予想される動作であることは知っていますが、nettyに各データグラムのパイプラインを再作成させる方法はありますか?それとも私はこれを完全に間違った方法で行っていますか?

簡潔に言えば、各データグラムにパイプラインの新しいインスタンス(tcpと同じ)を持たせたいです。

4

2 に答える 2

6

私がIRCで言ったように、それはあなたが望むことをするか、少なくともあなたにいくつかのアイデアを与えることができると思います。

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

    }
}
于 2012-04-27T11:21:21.997 に答える
0

UDPチャネルがどのように処理されるかはわかりませんが、チャネルがデータグラムごとに異なる場合は、状態をChannelLocalに保存できます。

于 2012-04-26T16:25:34.137 に答える