Communicating in Asynchronous World with Netty
In this chapter, we will cover asynchronous socket programming and common recipes using Netty for building network-based application. The user story is, you get requirements to develop a system, that client and server can communicate asynchronously using TCP/IP . So we will divide the problem to 6 common recipes:
Building an asynchronous TCP/IP server and client
Sending hello message to server when connection is ready
Receiving message asynchronously
Get callback when closing an active Channel
Get notification from ChannelHandler states
Data pipeline processing with ChannelHandler
Introduction
Before we go to the first recipe, we need to ask ourselves for the key question of first chapter: Why …show more content…
The advantages are improving throughput, latency, and/or responsiveness.
Channel I/O in Netty is designed to maximize CPU utilization and throughput by offloading most I/O onto a coprocessor, by using Zero-Copy Networking.
The context of our problem is when your application receives all data from peers, you want to close channel and add a listener to get notification when the operation completes.
How to do it …
Implement the interface GenericFutureListener to get notification when a TCP channel close successfully.
@Sharable
public class TcpServerOutboundHandler extends ChannelOutboundHandlerAdapter { @Override public void flush(ChannelHandlerContext ctx) throws Exception …show more content…
// the Decoder p.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8)); // the Encoder p.addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8)); // the log handler and data transformer p.addLast("logger",new MessageToMessageDecoder<String>(){ @Override protected void decode(ChannelHandlerContext ctx, String msg,List<Object> out) throws Exception { logger.info(String.format("logged raw data '%s'", msg)); InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress(); Map<String, String> request = new HashMap<>(); request.put("data", msg); request.put("from-ip", address.getAddress().getHostAddress()); out.add(request); } }); // the processing logic handler p.addLast("handler",new SimpleChannelInboundHandler<Map<String, String>>(){ @Override public void channelRead0(ChannelHandlerContext ctx, Map<String, String> request) throws Exception { logger.info(String.format("from-host: '%s'", request.get("from-ip"))); logger.info(String.format("data: '%s'", request.get("data"))); ctx.writeAndFlush("Done");