Netty+Service+BroadCast实现TCP 长连接

2020-06-06  本文已影响0人  leap_

https://ifeve.com/socket-channel/
https://mp.weixin.qq.com/s/HhwaXd8x7zONr8N1ojSnsQ
https://www.jianshu.com/p/f4ee6b1cd8c4

https://baijiahao.baidu.com/s?id=1652411987807894303&wfr=spider&for=pc
https://github.com/code4craft/netty-learning/blob/master/posts/ch1-overview.md

Netty:

传统的网络通信框架通常是开启一个子线程,在子线程中创建一个Socket连接,通过Socket连接去向服务端请求数据,在等待服务端返回数据的时候会发生阻塞,如果请求越来越多,那么因网络等待被阻塞的线程也会越来越多

传统的网络请求

为了解决上面的问题,提出了使用NIO实现的Netty网络框架,每次客户端请求,会创建一个SocketChannel,并且将其注册到Selector(多路复用器),Selector关注服务端数据的IO有没有到来,线程不需要等待IO,可以做自己的事情


基于NIO的Netty网络请求

Netty核心组件:

Channel:(Socket)

当客户端和服务端建立连接时会创建一个Channel,可以理解为Socket连接,负责基本的IO操作;

EventLoop:(监控+通知)

服务器发出消息称为出站,服务器接收的消息称为入站,消息的出站和入站会产生事件(Event),EventLoop用于监控和协调事件,在Netty中每一个channel都会分配一个EventLoop为其服务,一个EventLoop可以服务多个Channel;每一个EventLoop会占用一个线程,这个 Thread 会处理 EventLoop 上面发生的所有 IO 操作和事件;

EventLoopGroup:

EventLoopGroup是用于创建EventLoop的,EventLoopGroup中可以存放多个EventLoop

Netty实现单线程多任务核心思想:EventLoop可以监控服务端的数据,当数据到达时会通知客户端去处理,在等待的时候,客户端线程可以去做别的事情;传统思想是一个Channel(Socket)对应一个Thread,Netty是一个EventLoop对应一个线程,而EventLoop可以对应多个Channel(Socket)

ChannelHandler:事件处理者

每一次请求都会出发事件,事件由Handler处理,处理顺序由ChannelPipeline决定

ChannelPipeline: (事件排队)

ChannelPipeline为ChannelHandler提供了容器,pipeLine 保证了 handler 按照一定顺序处理事件,当事件发生后,会将数据按照一定的顺序通过pipeLine传给handler,同时,ChannelPipeline 也可以添加或者删除 ChannelHandler,管理整个队列。

ChannelHandlerContext : (传递消息给handler)

每当有 ChannelHandler 添加到 ChannelPipeline 时,同时会创建 ChannelHandlerContext 。ChannelHandlerContext 的主要功能是管理 ChannelHandler 和 ChannelPipeline 的交互。ChannelHandlerContext 参数贯穿 ChannelPipeline,将信息传递给每个 ChannelHandler

上述核心组件总结:


EventLoop  &  EventLoopGroup ChannelPipeline & ChannelHandlerContext

Bootstrap:

Bootstrap是netty的引导类,用于netty的配置和连接的建立;Bootstrap有两个实现类:

Bootstrap(客户端引导)需要一个 EventLoopGroup,但是 ServerBootstrap(服务端引导)则需要两个 EventLoopGroup。因为服务器需要两组不同的 Channel。第一组 ServerChannel 自身监听本地端口的套接字。第二组用来监听客户端请求的套接字。

Netty实现长连接

通过心跳机制,定时发送一个数据,配合Service+BroadCasetReceiver,实现长连接实时推送股票的最新数据

由于公司的代码不能乱贴,就随便写写画画吧,大概说个意思

  1. 创建bootstrap对象配置netty,设置channel类型,设置handler顺序,添加自定义handler,

  2. bootstrap.connect()建立连接;

  3. 创建一个Service,在服务中根据业务推送相应的数据,同时注册一个广播接收器,在屏幕关闭时断开TCP连接,屏幕亮起时开启连接;

  4. 实时推送的核心是自定义的这个handler,在自定义的handler中,重写userEventTriggered(),在这个方法中发送心跳包;

自定义handler:
public class MyHandler extends SimpleChannelInboundHandler {

    @Override   // 处理数据
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
    }

    @Override    //  发送心跳包
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        super.userEventTriggered(ctx, evt);
    }
}
上一篇下一篇

猜你喜欢

热点阅读