netty学习笔记【不断更新】

git 地址:https://github.com/chris1132/netty_lecture
2018-7-20
开始系统学习netty
完成服务端部分
https://blog.csdn.net/u010530712/article/details/82107187html

2018-7-22html5

实现客户端和服务端基于tcp双向通讯java

源码 https://github.com/chris1132/netty_lecture/src/main/java/com/chovy/netty/secondeexample
2018-7-24
一、netty自己不是按照servlet规则;
二、http是请求响应模式的无状态的协议,对于netty是监听tcp的端口号,对于他们底层来讲还是serversocket;
三、对于springmvc程序来讲,运行在jetty、Tomcat这些servlet容器上,这些容器保证链接关闭,对于netty,链接能够本身控制如keepalive时间
python

2018-7-25git

一、netty对请求路由没提供支持;github

二、netty完成socket相关开发;支持长链接开发;web

三、websocket实现客户端与服务端的持续链接,可相互发消息。不须要封装不必的消息,如http中的header;spring

2018-7-26
一、SimpleChannelInboundHandler<T> T泛型,要处理的消息的 Java 类型;
二、ChannelHandler,ChannelHandlerContext,ChannelPipeline这三者的关系很特别,相辅相成,一个ChannelPipeline中能够有3多个ChannelHandler实例,而每个ChannelHandler实例与ChannelPipeline之间的桥梁就是ChannelHandlerContext实例,
ChannelHandlerContext用于得到上下文信息,如得到远程地址。
一个channelPipeline中有多个channelHandler时,且这些channelHandler中有一样的方法时,例如channelActive方法,只会调用处在第一个的channelHandler中的channelActive方法,若是想要调用后续的channelHandler的同名的方法就须要调用以“fire”为开头的方法,如ctx.fireExceptionCaught(cause);bootstrap

三、EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();浏览器

NioEventLoopGroup是用来处理I/O操做的多线程事件循环器,Netty提供了许多不一样的EventLoopGroup的实现用来处理不一样传输协议。咱们实现了一个服务端的应用,会有2个NioEventLoopGroup会被使用。第一个常常被叫作‘boss’,用来接收进来的链接。第二个常常被叫作‘worker’,用来处理已经被接收的链接,一旦‘boss’接收到链接,就会把链接信息注册到‘worker’上。如何知道多少个线程已经被使用,如何映射到已经建立的channel上都须要依赖于EventLoopGroup的实现,而且能够经过构造函数来配置他们的关系。

服务器端 bootstrap.childHandler   客户端:bootstrap.handler
handler针对的是boss发挥做用,处理boss相关信息,如:链接来了后,处理相关日志输出;
childhandler针对worker,boss把链接交给worker后,由childhandler里面对象对worker里面nio线程发挥做用

2018-7-27

netty 多客户端链接与通讯 
实现多客户端链接,
需求1:A、B、C-》Server,一、A链接,二、B链接,S打印B链接,S告诉A,B上线,三、C上线,S打印C上线,广播给AB,通知C上线
需求2:ABC都创建链接,A发消息,ABC都受到消息,A显示本身发的消息,BC显示消息来自A

经过handlerAdded,获取添加的channel,使用channelgroup,向channel组里的已有通道广播

源码 https://github.com/chris1132/netty_lecture/src/main/java/com/chovy/netty/thirdexample

##netty读写检测机制与长链接要素------心跳

一、手机端和服务器端创建长链接,客户端没退出应用,而后客户端开了飞行模式,则服务器端与客户端没法感知链接已断,相应方法如handlerRemoved方法不会调用。 经过心跳,app向服务器端发心跳包,服务器端收到后,再向app发送ack。若是客户端长时间没法收到反馈消息,则断开

二、IdleStateHandler用来检测空闲状态,设置读写操做有效时间, userEventTriggered 出发某个事件被触发后调用该方法,将事件转发给管道pipeline的下一个handler对象。userEventTriggered 某个事件被触发后调用该方法,将事件转发给管道pipeline的下一个handler对象

源码 https://github.com/chris1132/netty_lecture/src/main/java/com/chovy/netty/fourthexample

2018-7-30

netty对websocket的支持

1、websocket解决http存在的问题, 一、http是无状态的,客户端发送两次请求,单从协议自己没法识别两次关系、存了哪些信息,像cookie、session用来解决这些问题, 二、基于请求响应模式的协议,http1.0中请求与响应以前先创建链接,请求发起方是浏览器,响应完成后断开链接,如此反复。HTTP1.1,增长keep-alive,客户端和服务端保持一个短期的持续链接,这个时间内,客户端与服务端只会创建一个连接,以后的请求复用该链接

2、假长链接,运用轮询的结束,客户端定时发请求,http包含两部分,header和body,header必带,头信息占据的大小远大于内容。

3、websocket实现浏览器与服务器之间的长链接,双方是对等的实体,能够互发信息。长链接在初次创建的时候,客户端向服务端发送请求(包括头信息),以后不用包括头信息,真正发送数据自己

websocket自己是构建在http协议上的升级版协议,客户端向向服务器端发请求创建链接(http链接),header里携带了websocket相关的参数,根据这些参数,服务端经过upgrade这个操做把http链接升级成websocket

websocket是html5规范的一部分

2018-7-31

一、netty 对于处理请求是分块或分段方式,客户端向服务端发送请求,长度1000,netty可能会分红10段,每段会走一个完整的流程,咱们本身处理器的channelread0,只读到一段

二、HttpObjectAggregator(len)把分段的请求(响应)聚合成一个完整的请求(响应),len以字节的方式来聚合内容的最大长度,若是聚合的内容超过了长度,调用handleOversizedMessage

三、WebSocketServerProtocolHandler 会处理关于websocket繁重的工做,负责链接握手、以及处理心跳相关的内容,WebSocketServerProtocolHandler("/ws")其中/ws是指websocket uri的地址 如ws://localhost:8899/'ws' WebSocketServerProtocolHandler的ws是指请求地址里的第二个ws

##netty实现服务端和客户端的长链接通讯

源码 https://github.com/chris1132/netty_lecture/src/main/java/com/chovy/netty/fifthexample
需求,实现网页经过websocket发送数据,服务端收到后反馈消息
在浏览器的ws:/localhost:8899/ws  header中,Status Code:101 Switching Protocols,转换协议  http->ws
在请求头里Request Headers里Upgrade:websocket,虽然访问ws这个请求,可是须要http先去创建链接,创建完成后,再upgrade(升级)到websocket,因此说websocket是在http之上的协议

2018-8-1

##google protobuf使用方式

源码 https://github.com/chris1132/netty_lecture/src/main/java/com/chovy/netty/sixthexample
1、protobuf 进行rpc数据传输,用来自定协议,能够更好的、体积更小的对数据编码解码,即序列化反序列化(编码、解码)过程。rpc开发中经常使用的库
2、RMI:remote method invocation,远程方法调用。(只针对java,client和server都必须是java) 客户端:stub,服务端:skeleton
经过网络传输,A->(调用的对象、方法、参数)序列化成字节码-》网络传输-》B-》接收字节码,反序列化转换成,调用特定对象、方法。
RPC:remote procedure call 远程过程调用  用socket传输
RPC比RMI的优点,跨语言调用,如客户端用python,服务端用java,客户端能够调用本身的一个方法,触发服务端的方法
RPC编写模式,:
一、定义接口说明文件(idl):描述对象、对象成员、接口方法等一系列信息。
二、经过rpc框架所提供的编译器,将接口说明文件编译成具体文件
三、在客户端与服务器端分别引入RPC编译器所生成的文件,便可像调用本地方法同样调用远程方法
决定rpc框架效率看编解码效率
在公司内网中更推荐用rpc方式进行,减小基于http通讯带来的损耗。
2018-8-2
使用protocol-buffer构建对象,实现编解码
需求,客户端A,服务器B,A构造对象,发给服务器端,B收到后,打印对象信息,把另外一个对象发给A。

用proto文件建立java代码指令,protoc -I=src/protobuf  --java_out=src/main/java src/protobuf/StuffInfo.proto

2018-8-3
接昨天,已完成昨天需求,待解决问题
pipeline.addLast(new ProtobufDecoder(StuffInfo.Teacher.getDefaultInstance()))   //StuffInfo.Teacher编码对象写死,不灵活,

2018-8-6
解决方案,在发送消息外再包一层,见StuffInfo.proto,经过枚举列举各消息类型,再经过一个字段标识本次消息传递的是哪一个消息类型
netty基于protocolbuffer这种数据传递过程,对于具体用哪一种方法或数据类型来处理请求,存在判断繁杂问题,由于,一段向另外一段发送数据时候,接收方要能判断对方发送哪一种数据类型,经过if-else去寻找匹配的数据类型
而springmvc和netty相比比,springmvc路径路由很清晰直观,如: @RequestMapping(value="../xx/",method=RequestMethod.GET),下面对于一个处理方法。由于springmvc 有dispatcherServlet(控制器),c向s发起的全部请求,
都通过dispatcherServlet,再分发给不一样的controller,springmvc在启动的时候,找到url和方法对应关系,把对应关系保存(如map),s收到请求后,经过url匹配具体方法。

使用Git做为版本控制系统

不建议。。git submodule:  git 仓库里的一个仓库,如netty_lecture是已有的工程,protobuf生成的java代码为protobuf-java工程,经过git submodule把protobuf-java引入到netty_lecture,当protobuf-java本地发生变化,提交远程仓库后,切到netty_lecture目录下,经过git pull,把protobuf-java更新到netty_lecture。问题:分支切换紊乱,A中引入了中间工程B,若在A中对B进行修改,在把B更新到远程仓库,会发生错误

建议。。git subtree

##io、nio回顾 https://blog.csdn.net/u010530712/article/details/82021416

2018-8-27

###零拷贝深刻剖析及用户空间与内核空间切换方式###

http://www.javashuo.com/article/p-exgadnoe-hd.html