netty同时做HTTP和websocket服务器并且实现HTTP路由的思路
来源:互联网 发布:unix编程环境 pdf 编辑:程序博客网 时间:2024/06/03 13:39
近期需要给别人做一个HTTP加Websocket的处理后端,果断选了spring+netty的组合,spring提供IOC容器+AOP+事务,netty处理IO,但是netty提供的HTTP比较底层,还需要自己处理路由,,,还是比Servlet麻烦不少,于是陆续将自己学习和编码过程中一些东西写出来,希望能帮的到别人。用的是netty5
学习netty用到的资源
- 官网的API文档
- 《netty权威指南》,给很多步骤做出了解释,没解释的看API
- 官方的demo,下载netty-example-5.0.0.Alpha2-sources.jar源码包解压,给出了很多Demo
- 博客1 博客2 还有很多
- Github,netty项目很多,分析下源码
server端编码,主要讲一下channel中的handler
- HttpServerCodec:ByteBuf->HttpRequest或HttpContent和HttpResponse或者HttpContent->ByteBuf,即HTTP请求的解码和编码
- HttpObjectAggregator:把多个消息转换为一个单一的FullHttpRequest或是FullHttpResponse,原因是HTTP解码器会在每个HTTP消息中生成多个消息对象HttpRequest/HttpResponse,HttpContent,LastHttpContent
- WebSocketServerCompressionHandler:WebSocket数据压缩(可选)
- ChunkedWriteHandler:大文件支持(没有写在代码中,可选)
- HttpHandler:自定义的HTTP和Websocket处理类,二者处理也可以分开在多个ChannelHandler中,在这里写在一个Handler中
- handler方法和childHandler方法区别
- handler存在于AbstractBootstrap,目的是添加一个handler,监听Bootstrap动作,它在初始化时就会执行
- childHandler存在于ServerBootstrap,目的是添加一个handler,监听已经连接的客户端的Channel的动作和状态,在客户端连接成功后才执行。
- option方法和childOption方法区别
- option存在于AbstractBootstrap,提供给NioServerSocketChannel用来接收进入的连接。
- childOption存在于ServerBootstrap ,提供给ServerChannel接收已经建立的连接。
- handler方法和childHandler方法区别
public void run(final int port) throws InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast("respDecoder-reqEncoder", new HttpServerCodec()) .addLast("http-aggregator", new HttpObjectAggregator(65536)) .addLast(new WebSocketServerCompressionHandler()) .addLast("action-handler", new HttpHandler()); } }); ChannelFuture future = b.bind(new InetSocketAddress(port)).sync(); logger.info("The http server powered by netty is listening on " + port); future.channel().closeFuture().sync();//阻塞处理,等待服务端链路关闭之后main函数才退出 } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }
自定义的ChannelHandler,用于处理HTTP和Websocket
区别HTTP和Websocket请求
@Override public void messageReceived(ChannelHandlerContext ctx, Object msg) { if (msg instanceof FullHttpRequest) {//如果是HTTP请求,进行HTTP操作 handleHttpRequest(ctx, (FullHttpRequest) msg); } else if (msg instanceof WebSocketFrame) {//如果是Websocket请求,则进行websocket操作 handleWebSocketFrame(ctx, (WebSocketFrame) msg); } }
上面的Object类型的msg就是extends SimpleChannelInboundHandler<Object>中的Object,我们可以定义ChannelHandler时将Object换成FullHttpRequest,这样就只处理HTTP请求,换成WebSocketFrame只处理websocket
HTTP请求的分发
//处理HTTP的代码 private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) { HttpMethod method=req.method(); String uri=req.uri(); diapathcer(method,uri); }private void diapathcer(HttpMethod method,String uri){ if(method==HttpMethod.GET&&"/login".equals(uri)){ //....处理 }else if(method==HttpMethod.POST&&"/register".equals(uri)){ //...处理 } }
- 实际中路由不会这样写,我们可以自定义路由的实现,写在一个类中专门实现路由,或者自定义一个配置文件,像properties一样,每一行格式形如:(GET \login LoginAction),我们知道properties是继承HashTable(String,String),我们可以自定义配置文件的对应类继承HashMap(String,HashMap(String,String)),我自己已经将路由和路由配置文件的实现完成,以后会陆续公开
自定义ChannelHandler代码
public class HttpHandler extends SimpleChannelInboundHandler<Object> { @Override public void messageReceived(ChannelHandlerContext ctx, Object msg) { if (msg instanceof FullHttpRequest) {//如果是HTTP请求,进行HTTP操作 handleHttpRequest(ctx, (FullHttpRequest) msg); } else if (msg instanceof WebSocketFrame) {//如果是Websocket请求,则进行websocket操作 handleWebSocketFrame(ctx, (WebSocketFrame) msg); } } @Override public void channelReadComplete(ChannelHandlerContext ctx) { ctx.flush(); } //处理HTTP的代码 private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) { HttpMethod method=req.method(); String uri=req.uri(); diapathcer(method,uri); } private void diapathcer(HttpMethod method,String uri){ if(method==HttpMethod.GET&&"/login".equals(uri)){ //....处理 }else if(method==HttpMethod.POST&&"/register".equals(uri)){ //...处理 } } //处理Websocket的代码 private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); }}
文/jcala(简书作者)
原文链接:http://www.jianshu.com/p/5c29c6c6d28c
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
原文链接:http://www.jianshu.com/p/5c29c6c6d28c
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
0 0
- netty同时做HTTP和websocket服务器并且实现HTTP路由的思路
- netty实现http服务器
- 用Netty实现的简单HTTP服务器
- 用Netty实现的简单HTTP服务器
- 用Netty实现的简单HTTP服务器
- Play框架的Netty Http服务器实现
- Netty实现简单HTTP服务器
- netty实现websocket(一)----HTTP与WebSocket
- netty 对 http 的实现
- netty服务器搭建-http
- Netty 实现HTTP文件服务器
- Netty 实现HTTP文件服务器
- Netty 实现HTTP文件服务器
- Shell 做的 HTTP 服务器
- 使用netty构建http服务器
- http与websocket的相同点和不同点
- 理清WebSocket和HTTP的关系
- WebSocket和HTTP的区别与联系
- 2016.12.11总结
- Binary Tree Level Order Traversal II
- CentOS6.5系统下RPM包安装MySQL5.6
- windows7_32位系统下添加mongodb到windows服务
- 内联函数(inline)
- netty同时做HTTP和websocket服务器并且实现HTTP路由的思路
- Unable to resolve target 'android-19'
- MAC下tomcat的使用教程
- 支付类App,支付功能的测试思路有哪些?
- 如何用Moco-runner搭建测试服务器?
- 字符串长度
- ShowDoc学习一
- 暴雪hash murmurhash3 cityhash 性能对比
- 爬取起点小说