Sending and receiving ArrayList Objects or Array Objects in Netty

别等时光非礼了梦想. 提交于 2020-01-16 20:09:07

问题


Hello all I am really new to netty. What I want is something like this. On my client I want to enter a String query example SELECT * FROM drivers. I am using an mysql xampp server. Then my server will query it down and add it to arraylist

 private List<Drivers> getRecords(ResultSet rs) throws SQLException {

        List<Drivers> records = new ArrayList<Drivers>();
        while(rs.next()){
            records.add(new Drivers(rs.getInt("first_name"), rs.getString("last_name")));
        }
        return records;
    }

After that it will send ArrayList objects back to the client.

My problem now is on how to populate it to the client

Here is my server pipeline

public class ServerInitializer extends ChannelInitializer<SocketChannel> {

    private final SslContext sslCtx;

    public ServerInitializer(SslContext sslCtx) {
        this.sslCtx = sslCtx;
    }

    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();

        // Add SSL handler first to encrypt and decrypt everything.
        // In this example, we use a bogus certificate in the server side
        // and accept any invalid certificates in the client side.
        // You will need something more complicated to identify both
        // and server in the real world.
        pipeline.addLast(sslCtx.newHandler(ch.alloc()));

        // On top of the SSL handler, add the text line codec.
        /*
        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast(new StringDecoder());
        pipeline.addLast(new StringEncoder());
          */
        //pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        /*

        */
        //pipeline.addLast("frameDecoder",new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4));
        //pipeline.addLast("bytesDecoder",new ByteArrayDecoder());
        pipeline.addLast(new ObjectEncoder());
        pipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));

        // and then business logic.
        pipeline.addLast(new ServerHandler());
    }
}

My Client Pipeline

 public class ClientInitializer extends ChannelInitializer<SocketChannel> {

        private final SslContext sslCtx;

        public ClientInitializer(SslContext sslCtx) {
            this.sslCtx = sslCtx;
        }

        @Override
        public void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();

            // Add SSL handler first to encrypt and decrypt everything.
            // In this example, we use a bogus certificate in the server side
            // and accept any invalid certificates in the client side.
            // You will need something more complicated to identify both
            // and server in the real world.
            pipeline.addLast(sslCtx.newHandler(ch.alloc(), Client.HOST, Client.PORT));

            // On top of the SSL handler, add the text line codec.

            /*
            pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
            pipeline.addLast(new StringDecoder());
            pipeline.addLast(new StringEncoder());
              */
            //pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
            /*
            */
            pipeline.addLast("frameDecoder",new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4));
            pipeline.addLast("bytesDecoder",new ByteArrayDecoder());
            pipeline.addLast(new ObjectEncoder());
            pipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
            // and then business logic.
            pipeline.addLast(new ClientHandler());
        }
    }

My Server Channel Handler

public class ServerHandler extends ChannelInboundHandlerAdapter {

    static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    public void channelActive(final ChannelHandlerContext ctx) {
        // Once session is secured, send a greeting and register the channel to the global channel
        // list so the channel received the messages from others.
        ctx.pipeline().get(SslHandler.class).handshakeFuture().addListener(
                new GenericFutureListener<Future<Channel>>() {
                    @Override
                    public void operationComplete(Future<Channel> future) throws Exception {

                        channels.add(ctx.channel());
                    }
        });
    }

    private List<Drivers> getRecords(ResultSet rs) throws SQLException {

        List<Drivers> records=new ArrayList<Drivers>();
        while(rs.next()){
            records.add(new Drivers(rs.getInt(0), rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), 
                    rs.getString(5), rs.getString(6), rs.getInt(7), rs.getString(8), rs.getString(9), rs.getString(10), 
                    rs.getString(11), rs.getString(12), rs.getString(13), rs.getString(14), 
                    rs.getString(15), rs.getString(16), rs.getString(17), rs.getString(18), rs.getString(19)));
        }
        return records;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
    {
         // Send the received message to all channels but the current one.
        for (Channel c: channels) {
            if (c != ctx.channel()) {
                c.writeAndFlush("[" + ctx.channel().remoteAddress() + "] " + msg + '\n');

            } else {

                try {
                    new DataManipulator();
                    System.out.print(msg.toString());
                    ResultSet rs = DataManipulator.generalQuery(msg.toString());
                    c.writeAndFlush(getRecords(rs));

                } catch (ClassNotFoundException | InstantiationException
                        | IllegalAccessException | SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        // Close the connection if the client has sent 'bye'.
        if ("bye".equals(msg.toString().toLowerCase())) {
            ctx.close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

My Client Channel Handler

public class ClientHandler extends SimpleChannelInboundHandler<Object[]> {

     static int count = 1;
     @Override
     public void channelActive(final ChannelHandlerContext ctx) {
         System.out.println(ctx.read());
     }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object[] msg)
            throws Exception {
        // Still don't know how to receive the data.

    }
}

Please help how to perfectly done this on netty.


回答1:


You don't need ByteArrayDecoder and LengthFieldBasedFrameDecoder in your pipeline. What you need are ObjectDecoder and ObjectEncoder, and that should be all (except for your last handler.)




回答2:


I happened to solved this problem with a little trick. In your case, I think the following sample code might help.

By defined A NettyMessage Class

public class NettyMessage implements Serializable{

    private static final long serialVersionUID = 1L;
    private  String action;
    private  List<Drivers> body;
    // getter and setter....

And within ServerHandler,

public void channelRead(ChannelHandlerContext ctx, Object msg) {
    List<Drivers> list = c.writeAndFlush(getRecords(rs));
    ctx.writeAndFlush(new NettyMessage("myaction", list));
}

within ClientHandler,

public void channelRead(ChannelHandlerContext ctx, Object msg) {
    NettyMessage message = (NettyMessage)msg;
    List<Drivers> driverList = message.getBody();
}

but don't extends SimpleChannelInboundHandler



来源:https://stackoverflow.com/questions/30465408/sending-and-receiving-arraylist-objects-or-array-objects-in-netty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!