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.