netty的消息处理
我们知道netty中所有的消息处理都是通过handler来实现的,为了方便起见,netty提供了一个简单的消息处理类SimpleChannelInboundHandler,大家通过继承它来重写channelRead0方法即可:
public abstract class SimpleChannelInboundHandler extends ChannelInboundHandlerAdapter
可以看到SimpleChannelInboundHandler本身是带有泛型I的,而这个I就是我们要探讨的方向。
如果我们只需要处理String消息,那么可以这样:
@Override
protected void channelRead0(ChannelHandlerContext ctx, String message)
throws Exception {
System.out.println(message);
}
}
同样的,如果要同时处理HTTP和WebSocket消息,只需要将I设置为不同的类型即可。
public class Server2FrameHandler extends SimpleChannelInboundHandler
对于FullHttpRequest,我们有:
BinaryWebSocketFrame
CloseWebSocketFrame
ContinuationWebSocketFrame
PingWebSocketFrame
PongWebSocketFrame
TextWebSocketFrame
其中真正包含内容的是TextWebSocketFrame和BinaryWebSocketFrame,这里我们对TextWebSocketFrame进行专门处理:
if (frame instanceof TextWebSocketFrame) {
// 将接收到的消息转换成为大写
String request = ((TextWebSocketFrame) frame).text();
ctx.channel().writeAndFlush(new TextWebSocketFrame(request.toUpperCase(Locale.CHINA)));
} else {
String message = "不支持的Frame类型: " + frame.getClass().getName();
throw new UnsupportedOperationException(message);
}
}
处理HTTP
对于HTTP请求中的FullHttpRequest,我们就安装正常的HTTP服务请求的处理流程来就行。
编码和解码器
等等,我们是不是忘记了什么东西?对,那就是编码和解码器。
没关系,netty为我们提供了一个WebSocketServerProtocolHandler类,专门负责websocket的编码和解码问题。
对于剩下的Text或者Binary frame数据,会被交由pipline中的下一个handler进行处理。
HANDSHAKE_COMPLETE 和 HANDSHAKE_TIMEOUT。
最后,将WebSocketServerProtocolHandler加入到pipeline中,最终得到:
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
pipeline.addLast(new Server2HttpHandler());
pipeline.addLast(new Server2FrameHandler());
}
总结
一个分离了HTTP请求和webSocket请求的服务器就完成了。简单直观才是一个程序员追求的世界!
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/27721058/viewspace-2851480/ ,如需转载,请注明出处,否则将追究法律责任。