WebSocket

发布时间:2024年01月24日

1.短轮询

本质就是Web端不断向Server服务端发送一个HTTP请求,如果有新消息,则会将请求返回**(无数据:服务端立即返回空箱,客户端继续问)**
适用场景:
比如扫码登录,当用户扫码时,说明用户是有意向的,所以我们客户端就不断发送请求获取消息
小OA系统:客户量不大的情况。
缺点: 1.当用户量大,请求就会频繁发送,服务器就会频繁空响,当服务器没有新数据时也会产生较高的网络流量,浪费服务器的资源 2.无效请求很多
在这里插入图片描述

2.长轮询

过程: 1.客户端发送请求,询问数据——>2.若是服务器有新的数据,将数据一起返回,否则将请求挂起(超时时间),并保持连接**(短轮询:直接返回空响了)** ,当新数据到达时才会返回给客户端
请添加图片描述
优点: 1.大幅度降低了服务端对于无用的轮询的开销 2.降低了服务器处理请求QPS
缺点: 1.没有完全解决客户端无效请求的问题,因为有超时时间,过了超时时间后,若还没有数据达达,则会结束返回
2.服务端的压力还是比较大,因为只是降低了入口请求的QPS,但是因为要等待数据,所以并没有减少对后端资源轮询(相当于轮询从前端移到了后端)

3.WebSocket

是一个全双工通道
在这里插入图片描述
1.实现方式:
1.我们这里用的netty实现websocket ,因为netty是nio基于事件驱动的多路复用框架,即使用单线程或者少量线程能够处理大量并发连接;而Tomcat 是基于多线程的架构,每个连接都会分配一个线程,适合于并发量比较小的适合——>不过自T8.9之后Tomcat又引入了NIO模型
https://blog.csdn.net/weixin_57128596/article/details/126168054?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170609584116800186537976%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=170609584116800186537976&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-1-126168054-null-null.nonecase&utm_term=nio&spm=1018.2226.3001.4450(NIO学习)
NIO与BIO的比较

2.Netty 提供了丰富的功能和组件,可以灵活地构建自定义的网络应用。它具有强大的编解码器和处理器,可以轻松处理复杂的协议数据格式。Netty 的扩展性也非常好,可以根据需要添加自定义的组件。比如我们可以用netty的pipeline方便的进行前置后置的处理,可以用netty的心跳处理器检查连接的状态。这些都是netty的优势**(1.丰富的组件 2.编码译码器,处理器 3.扩展良好,易于添加组件 4.心跳处理器)**

3.netty实现websocket

客户端依靠发起HTTP握手,告诉服务端进行WebSocket协议通讯,并告知WebSocket协议版本。服务端确认协议版本,升级为WebSocket协议。之后如果有数据需要推送会主动推送给客户端
在这里插入图片描述
连接开始时,客户端使用HTTP协议和服务端升级协议,升级完成后,后续数据交换遵循WebSocket协议。我们看看Request Headers
在这里插入图片描述

public void run() throws InterruptedException {
    // 服务器启动引导对象
    ServerBootstrap serverBootstrap = new ServerBootstrap();
    serverBootstrap.group(bossGroup, workerGroup)
            .channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_BACKLOG, 128)
            .option(ChannelOption.SO_KEEPALIVE, true)
            .handler(new LoggingHandler(LogLevel.INFO)) // 为 bossGroup 添加 日志处理器
            .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    ChannelPipeline pipeline = socketChannel.pipeline();
                    //30秒客户端没有向服务器发送心跳则关闭连接
                    pipeline.addLast(new IdleStateHandler(30, 0, 0));
                    // 因为使用http协议,所以需要使用http的编码器,解码器
                    pipeline.addLast(new HttpServerCodec());
                    // 以块方式写,添加 chunkedWriter 处理器
                    pipeline.addLast(new ChunkedWriteHandler());
                    /**
                     * 说明:
                     *  1. http数据在传输过程中是分段的,HttpObjectAggregator可以把多个段聚合起来;
                     *  2. 这就是为什么当浏览器发送大量数据时,就会发出多次 http请求的原因
                     */
                    pipeline.addLast(new HttpObjectAggregator(8192));
                    //保存用户ip
                    pipeline.addLast(new HttpHeadersHandler());
                    /**
                     * 说明:
                     *  1. 对于 WebSocket,它的数据是以帧frame 的形式传递的;
                     *  2. 可以看到 WebSocketFrame 下面有6个子类
                     *  3. 浏览器发送请求时: ws://localhost:7000/hello 表示请求的uri
                     *  4. WebSocketServerProtocolHandler 核心功能是把 http协议升级为 ws 协议,保持长连接;
                     *      是通过一个状态码 101 来切换的
                     */
                    pipeline.addLast(new WebSocketServerProtocolHandler("/"));
                    // 自定义handler ,处理业务逻辑
                    pipeline.addLast(new NettyWebSocketServerHandler());
                }
            });
    // 启动服务器,监听端口,阻塞直到启动成功
    serverBootstrap.bind(WEB_SOCKET_PORT).sync();
    System.out.println("启动成功");
}

明白了websocket的升级过程,对netty的处理的就比较简单了。websocket初期是通过http请求,进行升级,建立双方的连接。

1.所以编解码器需要用到HttpServerCodec。

2.WebSocketServerProtocolHandler是netty进行websocket升级的处理器(目的升级http-ws)。在这期间会抹除http相关的信息,比如请求头啥的。如果想获取相关信息,需要在这之前获取。
里面的源代码有判断请求是否是http请求,如果是的话会组装一个握手响应类进行响应(handshake)——>如果成功就会发送成功的事件,失败的话就会返回失败饿事件
在这里插入图片描述

3.HttpHeadersHandler是我们自己的处理器。赶在websocket升级之前,获取用户的ip地址,然后保存到channel的附件里。

4.NettyWebSocketServerHandler是我们的业务处理器,里面处理客户端的事件。

5.IdleStateHandler实现心跳检测。

4.实现前后端交互

文章来源:https://blog.csdn.net/weixin_57128596/article/details/135822182
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。