如何将ObjectDecoder添加到netty服务器

Thu*_*fir 2 java io multithreading netty data-synchronization

服务器代码来自netty QOTM(Quote Of The Moment)示例:

package net.bounceme.dur.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import java.util.logging.Logger;

public final class Server {

    private static final Logger log = Logger.getLogger(Server.class.getName());

    public static void main(String[] args) throws InterruptedException {
        MyProps p = new MyProps();
        int port = p.getServerPort();
        new Server().pingPong(port);
    }

    private void pingPong(int port) throws InterruptedException {
        log.fine("which handler?");
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new ServerDatagramHandler());
            b.bind(port).sync().channel().closeFuture().await();
        } finally {
            group.shutdownGracefully();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是DatagramPacket处理程序:

package net.bounceme.dur.netty;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import java.util.Random;
import java.util.logging.Logger;

public class ServerDatagramHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    private static final Logger log = Logger.getLogger(ServerDatagramHandler.class.getName());
    private static final Random random = new Random();

    public ServerDatagramHandler() {
        log.info("..started..");
    }

    // Quotes from Mohandas K. Gandhi:
    private static final String[] quotes = {
        "Where there is love there is life.",
        "First they ignore you, then they laugh at you, then they fight you, then you win.",
        "Be the change you want to see in the world.",
        "The weak can never forgive. Forgiveness is the attribute of the strong.",};

    private static String nextQuote() {
        int quoteId;
        synchronized (random) {
            quoteId = random.nextInt(quotes.length);
        }
        return quotes[quoteId];
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        System.err.println(packet);
        if ("QOTM?".equals(packet.content().toString(CharsetUtil.UTF_8))) {
            ctx.write(new DatagramPacket(
                    Unpooled.copiedBuffer("QOTM: " + nextQuote(), CharsetUtil.UTF_8), packet.sender()));
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.severe(cause.toString());
    }
}
Run Code Online (Sandbox Code Playgroud)

我想切换到Quote处理程序:

package net.bounceme.dur.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.util.Random;
import java.util.logging.Logger;
import net.bounceme.dur.jdbc.Quote;

public class ServerQuoteHandler extends SimpleChannelInboundHandler<Quote> {

    private static final Logger log = Logger.getLogger(ServerQuoteHandler.class.getName());
    private static final Random random = new Random();

    public ServerQuoteHandler() {
        log.info("..started..");
    }

    // Quotes from Mohandas K. Gandhi:
    private static final String[] quotes = {
        "Where there is love there is life.",
        "First they ignore you, then they laugh at you, then they fight you, then you win.",
        "Be the change you want to see in the world.",
        "The weak can never forgive. Forgiveness is the attribute of the strong.",};

    private static String nextQuote() {
        int quoteId;
        synchronized (random) {
            quoteId = random.nextInt(quotes.length);
        }
        return quotes[quoteId];
    }

    @Override
    protected void channelRead0(ChannelHandlerContext chc, Quote quote) throws Exception {
        log.info(quote.toString());
        chc.writeAndFlush(new Quote(nextQuote()));
    }

}
Run Code Online (Sandbox Code Playgroud)

就我的目的而言,Quote它只是一个String包装器,只有一个字段,并toString返回引号.它implements Serializable当然和使用serialVersionUID.

当我查看乒乓球示例时,我看不到在服务器上添加ObjectEncoder的位置.

博客有这个片段:

 // Set up the pipeline factory.
 bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
  public ChannelPipeline getPipeline() throws Exception {
   return Channels.pipeline(
    new ObjectDecoder(ClassResolvers.cacheDisabled(getClass().getClassLoader())),
    new DateHandler()
   );
  };
 });
Run Code Online (Sandbox Code Playgroud)

但是,我如何将其实现到QOTM服务器中?我正在通过Netty in Action,但还没有找到解释这个问题的相关文本.这本书的文本都ObjectEncoder没有ObjectDecoder出现......?

也可以看看:

如何使用Netty发送对象?

Moh*_*-Aw 5

我添加像这样的编码器和解码器来发送各种POJO:

客户:

        bootstrap.handler(new ChannelInitializer<SocketChannel>() {
        @Override
        public void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(new ObjectEncoder());
            ch.pipeline().addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
            ch.pipeline().addLast(customHandler1);
            ch.pipeline().addLast(customHandler2);
            ch.pipeline().addLast(customHandler3);
        }
    });
Run Code Online (Sandbox Code Playgroud)

服务器:

        bootstrap.option(ChannelOption.SO_REUSEADDR, true);
        bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
                            ch.pipeline().addLast(new ObjectEncoder());
                            ch.pipeline().addLast(customHandler1);
                            ch.pipeline().addLast(customHandler2);
                            ch.pipeline().addLast(customHandler3);
                        }
                    });
Run Code Online (Sandbox Code Playgroud)