博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Netty 简单服务器 (三)
阅读量:6066 次
发布时间:2019-06-20

本文共 4317 字,大约阅读时间需要 14 分钟。

hot3.png

经过对Netty的基础认识,设计模型的初步了解,来写个测试,试试手感

上篇也说到官方推荐我们使用主从线程池模型,那就选择这个模型进行操作

 

需要操作的步骤:

  • 需要构建两个主从线程组
  • 写一个服务器入口启动器
  • 设置Channel双向通道
  • 配置线程池处理器,操作Channel
  • 监听机制,比如监听启动端口,监听服务器关闭等等

 

利用IDEA快速一键构建一个springboot项目,然后去maven仓库找netty依赖,找个4.x.x最新的依赖就可以,5.x.x的版本已经被废弃,不要使用

io.netty
netty-all
4.1.32.Final

 

简单的目录展示

55e9c573c19831fc2b6c7e5d25be1a50caf.jpg

 

为了简单直接测试,在启动类同级建一个NettyServer启动类,一个main方法就可以了,贴图:

package com.yus.netty;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;/** * Netty 启动类 * 简单实现客户端发送连接请求,服务器返回信息 */public class NettyServer {    public static void main(String[] args) throws InterruptedException {        // 1。定义两个主从线程组        // 主线程组 --- 用于接收客户端的连接,不处理事件,就是接任务的包工头        EventLoopGroup primaryGroup = new NioEventLoopGroup();        // 从线程组 --- 处理主线程组接收连接注册之后的事件,就是纯打工的        EventLoopGroup subGroup = new NioEventLoopGroup();        try {            // 2。服务启动器            ServerBootstrap bootstrap = new ServerBootstrap();            // 根据Netty选择不同的线程模型,选择不同的重载方法,这里是主从线程模型            // 业务的分配等功能,都由bootstrap负责处理,不需要我们处理            // .channel --- 设置通道类型            // .childHandler 针对[subGroup从线程组]处理每一个channel,可以选择实现类,也可以自定义内部类的方式构建            // 每一个Channel由多个handle共同组成管道(pipeline)            bootstrap.group(primaryGroup, subGroup)                    .channel(NioServerSocketChannel.class)                    .childHandler(new ChannelInit());            // 3。绑定启动端口,确保链接启动,使用sync同步等待端口启动完成            ChannelFuture future = bootstrap.bind(8088).sync();            // 4。用于监听关闭的Channel ,同步方式            future.channel().closeFuture().sync();        } finally {            //使用shutdownGracefully关闭 ,原shutdown方法已经过时            primaryGroup.shutdownGracefully();            subGroup.shutdownGracefully();        }    }}

 

初始化器

package com.yus.netty;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.http.HttpServerCodec;/** * 初始化器 --- 初始化每一个Channel * .channel设置的类型是泛型 */public class ChannelInit extends ChannelInitializer
{ /** * channel pipeline handle 三者的关系 * * 1。注册的channel通道 * 2。进入初始化器pipeline管道 * 3。pipeline包含多个handle,共同处理channel,也可以理解为拦截处理 */ @Override protected void initChannel(SocketChannel channel) throws Exception { //通过 channel 获取管道 ChannelPipeline pipeline = channel.pipeline(); //通过管道 添加handle ,name选填 //使用netty提供的一个编解码HttpServerCodec //HttpServerCodec:当请求到服务端,需要解码,然后响应客户端,需要编码 pipeline.addLast("HttpServerCodec",new HttpServerCodec()); //添加自定义的助手类 pipeline.addLast("HelloHandle",new HelloHandle()); }}

 

助手类

package com.yus.netty;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.Channel;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.http.*;import io.netty.util.CharsetUtil;/** * 自定义的助手类 * 

* 客户端向服务端发起请求之后,数据存放在缓冲区 * 然后服务端从缓冲区中读取,整体操作是一个入栈 *

* SimpleChannelInboundHandler 入栈 * 要往客户端写点东西返回,使用HttpObject */public class HelloHandle extends SimpleChannelInboundHandler

{ @Override protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception { Channel channel = ctx.channel(); System.out.println("远程地址:" + channel.remoteAddress()); //操作 缓冲区 参数(返回自定义字符串,字符集) 此处设置的字符集仅供ByteBuf使用 ByteBuf buf = Unpooled.copiedBuffer("Hello,Netty,会乱码吗?!", CharsetUtil.UTF_8); //构建响应,将buf数据返回 参数(http版本号,http返回状态,) FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf); //设置响应头部的数据类型以及长度,返回需要设置charset=UTF-8,针对response设置 response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain;charset=UTF-8"); response.headers().set(HttpHeaderNames.CONTENT_LENGTH,buf.readableBytes()); //把response响应到客户端 //write只将response写到缓冲区,writeAndFlush将response写到缓冲区,并刷到客户端 ctx.writeAndFlush(response); }}

 

启动访问: localhost:8088 

-----------------------------------------------------------

转载于:https://my.oschina.net/u/3829444/blog/2990127

你可能感兴趣的文章
单词统计
查看>>
输入一个数字计算圆的面积
查看>>
在Delphi中隐藏程序进程
查看>>
AngularJS PhoneCat代码分析
查看>>
MEF元数据应用说明
查看>>
maven错误解决:编码GBK的不可映射字符
查看>>
2016/4/19 反射
查看>>
SharePoint Wiki发布页面的“保存冲突”
查看>>
oracle 10g 数据库与客户端冲突导致实例创建无监听问题
查看>>
Delphi中读取文本文件的方法(实例一)
查看>>
Linux常用命令
查看>>
Android开源代码解读の使用TelephonyManager获取移动网络信息
查看>>
想说一点东西。。。。
查看>>
css知多少(8)——float上篇
查看>>
NLB网路负载均衡管理器详解
查看>>
水平添加滚动条
查看>>
PHP中”单例模式“实例讲解
查看>>
VS2008查看dll导出函数
查看>>
VM EBS R12迁移,启动APTier . AutoConfig错误
查看>>
atitit.细节决定成败的适合情形与缺点
查看>>