时间:2018年04月11日星期三
说明:本文部分内容均来自慕课网。@慕课网:https://www.imooc.com
教学源码:https://github.com/zccodere/s...
学习源码:https://github.com/zccodere/s...
第一章:课程介绍
1-1 课程介绍
什么是Netty
- 高性能、事件驱动、异步非阻塞的IO Java开源框架
- 基于NIO的客户端,服务端编程框架
- 非常可靠的稳定性和伸缩性
Netty使用场景
- 高性能领域:游戏、大数据、分布式计算
- 多线程并发领域:多线程模型、主从多线程模型
- 异步通信领域:异步非阻塞,主动获取或通过通知机制来得到结果
课程提纲
- IO通信:BIO、伪异步IO、NIO、AIO通信
- Netty入门:原生NIO的缺陷、Netty的优势
- WebSocket入门:什么是WebSocket、如何建立连接、生命周期及关闭
- Netty实现WebSocket通信案例
课程要求
- 有一定的Java基础
- 有一定的IO编程基础
- 了解Java的BIO、伪异步IO、NIO和AIO
第二章:IO通信
2-1 IO通信
BIO通信
- 一个线程负责连接
- 一请求一应答
- 缺乏弹性伸缩能力
BIO通信模型
伪异步IO通信
- 线程池负责连接
- M请求N应答
- 线程池阻塞
伪异步IO通信模型
NIO通信
- 缓冲区Buffer
- 通道Channel
- 多路复用器Selector
AIO通信
- 连接注册读写事件和回调函数
- 读写方法异步
- 主动通知程序
四种IO对比
第三章:Netty入门
3-1 Netty入门
原生NIO的缺陷
- 类库和API繁杂
- 入门门槛高
- 工作量和难度大
- JDK NIO存在BUG
Netty的优势
- API使用简单,定制能力强,可以通过ChannelHandler对框架进行灵活的扩展
- 入门门槛低,功能强大,预制了多种编解码功能,支持多种主流协议
- 性能高,通过与其他的业界主流的NIO框架对比,Netty的综合性能最优
- Netty比较成熟稳定,Netty修复了JDK NIO所有发现的BUG
第四章:WebSocket入门
4-1 WebSocket入门
什么是WebSocket
- H5协议规范:H5提出的协议规范
- 握手机制:使客户端与服务器能够建立类似TCP的连接,方便通信
- 解决客户端与服务端实时通信而产生的技术:基于TCP的协议
WebSocket的优点
- 节省通信开销:以前使用轮询,开销较大
- 服务器主动传送数据给客户端:任意时刻,相互传送数据
- 实时通信:可以彼此相互推送信息
WebSocket建立连接
- 客户端发起握手请求
- 服务器响应请求
- 连接建立
WebSocket生命周期
- 打开事件:发生新的连接时调用、在端点上建立连接时且在任何事件之前
- 消息事件:接收WebSocket对话中,另一端发送的消息
- 错误事件:在进行连接或端点发生错误时产生
- 关闭事件:表示WebSocket端点的连接关闭
WebSocket关闭连接
- 服务器关闭底层TCP连接
- 客户端发起TCP Close
第五章:通信案例
5-1 通信案例
基于Netty实现WebSocket通信案例
功能介绍
- Netty开发服务端
- Html实现客户端
- 实现服务端与客户端的实时交互
代码编写
1.创建名为netty-websocket的maven工程pom如下
4.0.0
com.myimooc
netty-websocket
0.0.1-SNAPSHOT
io.netty
netty-all
5.0.0.Alpha1
org.apache.maven.plugins
maven-compiler-plugin
1.8
UTF-8
2.编写NettyConfig类
package com.myimooc.netty.websocket;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
/**
*
* 标题: Netty 全局配置类
* 描述: 存储整个工程的全局配置
*
* @author zc
* @date 2018/04/11
*/
public class NettyConfig {
/**
* 存储每一个客户端接入进来时的 Channel
*/
public static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
}
3.编写MyWebSocketHandler类
package com.myimooc.netty.websocket;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.CharsetUtil;
import java.util.Date;
/**
*
* 标题: 处理客户端WebSocket请求的核心业务处理类
* 描述: 接收/处理/响应 客户端websocket请求的核心业务处理类
*
* @author zc
* @date 2018/04/11
*/
public class MyWebSocketHandler extends SimpleChannelInboundHandler
4.编写MyWebSocketChannelHandler类
package com.myimooc.netty.websocket;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;
/**
*
* 标题: 初始化连接时的各个组件
* 描述: 初始化连接时的各个组件
*
* @author zc
* @date 2018/04/11
*/
public class MyWebSocketChannelHandler extends ChannelInitializer {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// 将请求和应答消息解码为HTTP消息
ch.pipeline().addLast("http-codec",new HttpServerCodec());
// 将HTTP消息的多个部分合成一条完整的HTTP消息
ch.pipeline().addLast("aggregator",new HttpObjectAggregator(65536));
// 向客户端发送HTML5文件
ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
ch.pipeline().addLast("handler",new MyWebSocketHandler());
}
}
5.编写AppStart类
package com.myimooc.netty.websocket;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
/**
*
* 标题: 程序入口
* 描述: 启动应用
*
* @author zc
* @date 2018/04/11
*/
public class AppStart {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workGroup);
serverBootstrap.channel(NioServerSocketChannel.class);
serverBootstrap.childHandler(new MyWebSocketChannelHandler());
System.out.println("服务端开启等待客户端连接...");
Channel channel = serverBootstrap.bind(8888).sync().channel();
channel.closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}finally {
// 优雅的退出程序
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
6.编写websocket.html
WebSocket客户端
第六章:课程总结
6-1 课程总结
课程总结
- 课程介绍
- IO通信:四种IO通信
- Netty入门:原生NIO的缺点,Netty的优点
- WebSocket入门:WebSocket的优点,如何使用
- 通信案例:Netty实现WebSocket通信案例