一、Netty简介
Netty是一个基于JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。换句话说,Netty是一个NIO框架,使用它可以简单快速地开发网络应用程序,比如客户端和服务端的协议。Netty大大简化了网络程序的开发过程比如TCP和UDP的 Socket的开发。Netty 已逐渐成为 Java NIO 编程的首选框架。
二、什么是物联网?
nio通信框架
三、物联网主要运用到Netty哪些特性?
1、TCP长连接 2、能够和各种序列化框架完美整合
四、为什么要使用Netty,相对于其他通信框架mina有哪些优点
1、API使用简单,开发门槛低 2、功能强大,预置了多种编解码功能,支持多种主流协议 3、社区活跃,版本更新快 4、技术稳定可靠,如:elasticsearch、spark、dubbo、motan等开源框架底层通信采用的是netty
五、Netty服务端编写
首先,Netty通过ServerBootstrap启动服务端代码,需要四步: 第一步,定义两个线程组,用来处理客户端通道的accept和读写事件 第二步,绑定服务端通道NioServerSocketChannel 第三步,给读写事件的线程通道绑定handle,处理具体的业务逻辑 第四步,绑定监听
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
/**
* Netty服务端编写
*
* @author ouyangfeng
*
*/
public class NettyServer {
public static void main(String[] args) throws InterruptedException {
// 首先,netty通过ServerBootstrap启动服务端
ServerBootstrap server = new ServerBootstrap();
EventLoopGroup parentGroup = new NioEventLoopGroup();
EventLoopGroup childGroup =new NioEventLoopGroup();
//第1步定义两个线程组,用来处理客户端通道的accept和读写事件
//parentGroup用来处理accept事件,childgroup用来处理通道的读写事件
//parentGroup获取客户端连接,连接接收到之后再将连接转发给childgroup去处理
server.group(parentGroup, childGroup);
//用于构造服务端套接字ServerSocket对象,标识当服务器请求处理线程全满时,用于临时存放已完成三次握手的请求的队列的最大长度。
//用来初始化服务端可连接队列
//服务端处理客户端连接请求是按顺序处理的,所以同一时间只能处理一个客户端连接,多个客户端来的时候,服务端将不能处理的客户端连接请求放在队列中等待处理,backlog参数指定了队列的大小。
server.option(ChannelOption.SO_BACKLOG, 128);
//第2步绑定服务端通道
server.channel(NioServerSocketChannel.class);
//第3步绑定handler,处理读写事件,ChannelInitializer是给通道初始化
server.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//解码器,接收的数据进行解码,一定要加在SimpleServerHandler 的上面
//maxFrameLength表示这一贞最大的大小
//delimiter表示分隔符,我们需要先将分割符写入到ByteBuf中,然后当做参数传入;
//需要注意的是,netty并没有提供一个DelimiterBasedFrameDecoder对应的编码器实现(笔者没有找到),因此在发送端需要自行编码添加分隔符,如 \r \n分隔符
ch.pipeline().addLast(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()[0]));
//把传过来的数据 转换成byteBuf
ch.pipeline().addLast(new SimpleServerHandler());
}
});
//第4步绑定8080端口
ChannelFuture future = server.bind(8080).sync();
//当通道关闭了,就继续往下走
future.channel().closeFuture().sync();
}
}
import java.nio.charset.Charset;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
/**
* 处理客户端返回的数据
*
* @author ouyangfeng
*
*/
public class SimpleServerHandler extends ChannelInboundHandlerAdapter {
/**
* 读取客户端通道的数据
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//可以在这里面写一套类似SpringMVC的框架
//让SimpleServerHandler不跟任何业务有关,可以封装一套框架
if(msg instanceof ByteBuf){
System.out.println(((ByteBuf)msg).toString(Charset.defaultCharset()));
}
//业务逻辑代码处理框架。。。
//返回给客户端的数据,告诉我已经读到你的数据了
String result = "hello client ";
ByteBuf buf = Unpooled.buffer();
buf.writeBytes(result.getBytes());
ctx.channel().writeAndFlush(buf);
ByteBuf buf2 = Unpooled.buffer();
buf2.writeBytes("\r\n".getBytes());
ctx.channel().writeAndFlush(buf2);
System.out.println("==========");
}
}
开启上面main方法。 执行一下命令 c:>telnet localhost 8080 随便输入,会发现控制台会监听到输入的内容,有个问题接收时一个字一个字接受,可以让他一行一行接收
六、Netty服务端输出的信息
{"age":12,"id":1,"name":"sssss"} ========== ssss0 ========== ssss1 ========== ssss2 ========== ssss3 ========== ssss4 ==========