【问题标题】:how to add ObjectDecoder to netty server如何将ObjectDecoder添加到netty服务器
【发布时间】:2014-08-03 01:30:33
【问题描述】:

服务器代码来自netty QOTM (Quote Of The Moment) example

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

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

我想切换到Quote Handler:

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

}

就我而言,Quote 只是一个字符串包装器,只有一个字段,toString 返回引号。它当然是implements Serializable,并使用serialVersionUID

当我查看ping-pong example 时,我没有看到在服务器上添加 ObjectEncoder 的位置。

A blog 有这个 sn-p:

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

但是,如何在 QOTM 服务器中实现它?我正在浏览Netty in Action,但还没有找到解释这一点的相关文字。 ObjectEncoderObjectDecoder 都没有出现在本书的正文中..?

另见:

How to send an object with Netty?

【问题讨论】:

    标签: java multithreading io netty data-synchronization


    【解决方案1】:

    我像这样添加编码器和解码器来发送各种 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);
            }
        });
    

    服务器:

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

    【讨论】:

    • 当您添加ObjectDecoderObjectEncoder 时,您是否也有custom en/de-coder?他们扩展MessageToMessageDecoder?
    猜你喜欢
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多