简体   繁体   中英

Sending and receiving ArrayList Objects or Array Objects in Netty

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.

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.)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM