Netty(三)Discard Server 与 Handler

Handler在netty中,占据非常重要地位,,与Servlet中的Filter很想,通过Handler可以完成通讯报文的解码和编码、拦截指定的报文、统一对日志错误进行处理、统一对请求进行计数、控制Handler执行与否。

Handler注册要注意先后顺序:

Handler按照输入输出区分,分为ChannelInboundHandler和ChannelOutboundHandler两类。ChannelInboundHandler对输入数据进行按照注册的先后顺序处理;而ChannelOutboundHandler对输出数据进行按照注册的先后顺序的逆序处理,如下图所示:

自定义Handler:

其中ServerHandler比ClientHandler简单,只需要负责接收消息、显示和返回应答就好了,代码如下所示:

Server端:

public class DiscardServerHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg)throws Exception {// 收到客户端的消息String toConsole = ctx.channel().remoteAddress() + " said: " + msg;System.out.println(toConsole);// 分发消息给客户端ctx.writeAndFlush(msg + " received!\r\n");}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}/** * 本方法channelActive在channel被accept时候(即连接建立的时候被触发) * @throws Exception */@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {String toConsole = ctx.channel().remoteAddress() + " active!";System.out.println(toConsole);ctx.writeAndFlush("Welcome to " + InetAddress.getLocalHost().getHostName() + " service!\r\n");super.channelActive(ctx);}}

上面的类继承了Class SimpleChannelInboundHandler<T>

其中T是泛型表达形式,在这里最简单的系统上我们设置为String,当然也可以设置为其他自定义的类,这会在后续博客中详细说明

需要覆盖的最基本的方法:

1)channelRead0:当服务器接收到channel发送来的消息的处理方法

2)channelActive():当服务器accept客户端的连接请求后触发的方法

3)其他:包括一些异常处理等

Client端:

public class DiscardClientHandler extends SimpleChannelInboundHandler<String> {// 用于保存消息//private ByteBuf content;private String content;// 用于回调的handlerprivate ChannelHandlerContext ctx;// 监听器private final ChannelFutureListener trafficGenerator = new ChannelFutureListener() {/* * 监听函数,用于在异步返回channelfuture的时候启动 */@Overridepublic void operationComplete(ChannelFuture future) throws Exception {if (future.isSuccess()) {System.out.println("Client is in listening!");generateTraffic();} else {future.cause().printStackTrace();future.channel().close();}}};@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg)throws Exception {String toConsole = "Server say: " + msg;System.out.println(toConsole);// Initialize and send the initial messagegenerateTraffic();}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {String toConsole = "Client active!";System.out.println(toConsole);this.ctx = ctx;super.channelActive(ctx);}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {String toConsole = "Client closed!";System.out.println(toConsole);super.channelInactive(ctx);}private void generateTraffic() throws IOException {// Flush the outbound buffer to the socket// Once flushed, generate the same amount of traffic againBufferedReader br = new BufferedReader(new InputStreamReader(System.in));content = br.readLine();//ctx.writeAndFlush(content + "\r\n").addListener(trafficGenerator);ctx.writeAndFlush(content + "\r\n");}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {// Close the connection when an exception is raisedcause.printStackTrace();ctx.close();}}

需要覆盖的最基本的方法:

1)channelRead0:当客户端接收到Server发送来的消息的处理方法,这里需要注意到的是,如果

2)channelActive():当服务器accept客户端的连接请求后触发的方法

3)channelInActive():当服务器断开与客户端的连接以后触发的方法

3)其他:包括一些异常处理等

自定义方法:

1)generateTraffic()

这个方法可以放在channelActive(若放在这里,需要添加Listener,因为Active方法只执行一次)或者channelRead0(若放在这里,必须不能添加Listener,不然Read方法将只能执行一次)

自定义类对象:

1)ChannelFutureListener

这个类用只有一个方法:当ChannelFuture的操作完成以后,需要做什么工作,是一个监听类,详细说明在后续的博客中

代替你主持夕阳的葬礼。

Netty(三)Discard Server 与 Handler

相关文章:

你感兴趣的文章:

标签云: