Netty实战应用学习笔记-中级拓展篇(五)

bugstack虫洞栈 | netty4.1案例文章列表汇总,跟着案例学Netty itstack-demo-netty netty4.x案例 微信公众号:bugstack虫洞栈,欢迎您的关注&获取更多案例与源码!博客栈:https://bugstack.cn 本专题针对netty4.x分为从;基础入门篇(九篇)、中级拓展篇(八篇)、高级应用篇(三章),由浅入深实现netty服务功能,介绍netty如何从上手到实战。 基础入门篇(九篇) netty案例,netty4.1... 阅读详情

💬 项目五:WebSocket 实时聊天系统

项目概述

项目名称:itstack-demo-netty-2-05
核心功能:基于WebSocket实现实时聊天系统,模仿微信聊天界面
技术要点:WebSocket协议、HTTP握手、ChannelGroup群发、JSP前端

为什么需要这个项目?

实际问题:

  • HTTP是单向通信,服务器无法主动推送消息
  • 轮询方式浪费资源,实时性差
  • 需要浏览器与服务器实时双向通信
  • 需要实现群发消息功能

解决方案:

  • ✅ WebSocket长连接:一次握手,持续通信
  • ✅ 双向通信:服务器可以主动推送消息
  • ✅ ChannelGroup:轻松实现消息群发
  • ✅ 低开销:握手后只传输数据,无HTTP头

适用场景:

  • 即时通讯(在线客服、企业聊天)
  • 实时推送(股票行情、新闻资讯)
  • 协同办公(在线文档、白板共享)
  • 游戏(多人在线游戏、实时对战)

核心知识点

1. WebSocket vs HTTP
特性HTTPWebSocket
连接方式短连接(请求-响应)长连接(持久连接)
通信方向单向(客户端→服务器)双向(客户端↔服务器)
实时性差(需要轮询)好(服务器主动推送)
开销大(每次请求都有HTTP头)小(握手后只传输数据)
应用场景普通网页浏览聊天、游戏、实时推送

类比理解:

  • HTTP:像发短信,你发一条,对方回一条
  • WebSocket:像打电话,一次接通,持续通话
2. Pipeline配置

MyChannelInitializer.java

public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel channel) {
        // 1. HTTP编解码器
        channel.pipeline().addLast("http-codec", new HttpServerCodec());
        
        // 2. HTTP消息聚合器(将多个HTTP消息聚合成一个完整的FullHttpRequest)
        channel.pipeline().addLast("aggregator", 
            new HttpObjectAggregator(65536));
        
        // 3. 分块写处理器(支持大文件传输)
        channel.pipeline().addLast("http-chunked", 
            new ChunkedWriteHandler());
        
        // 4. 自定义业务处理器
        channel.pipeline().addLast(new My
ServerHandler());
    }
}

三个核心编解码器:

编解码器作用
HttpServerCodecHTTP编解码器,处理HTTP请求和响应
HttpObjectAggregator将HTTP消息的多个部分聚合成完整的FullHttpRequest
ChunkedWriteHandler支持异步发送大文件,防止内存溢出
3. WebSocket握手处理

MyServerHandler.java

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    // 处理HTTP握手请求
    if (msg instanceof FullHttpRequest) {
        FullHttpRequest httpRequest = (FullHttpRequest) msg;
        
        // 1. 检查HTTP请求是否有效
        if (!httpRequest.decoderResult().isSuccess()) {
            // 返回400错误
            DefaultFullHttpResponse httpResponse = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST
            );
            ctx.channel().writeAndFlush(httpResponse);
            return;
        }
        
        // 2. 创建WebSocket握手工厂
        WebSocketServerHandshakerFactory wsFactory = 
            new WebSocketServerHandshakerFactory(
                "ws:/" + ctx.channel() + "/websocket", null, false
            );
        
        // 3. 执行握手
        handshaker = wsFactory.newHandshaker(httpRequest);
        if (handshaker == null) {
            WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(
                ctx.channel()
            );
        } else {
            handshaker.handshake(ctx.channel(), httpRequest);
        }
        return;
    }
    
    // 处理WebSocket消息
    if (msg instanceof WebSocketFrame) {
        handleWebSocketFrame(ctx, (WebSocketFrame) msg);
    }
}

WebSocket握手流程:

【客户端】                          【服务端】
    |                                  |
    | 1. 发送HTTP升级请求                |
    |  (Upgrade: websocket)            |
    |--------------------------------->|
    |                                  | 2. 验证请求
    |                                  | 3. 返回101状态码
    | 4. 接收握手响应                    |    (Switching Protocols)
    |<---------------------------------|
    | 5. 连接建立,开始WebSocket通信      |
4. WebSocket消息处理

处理不同类型的WebSocket帧:

private void handleWebSocketFrame(ChannelHandlerContext ctx, 
                                  WebSocketFrame frame) {
    // 1. 处理关闭请求
    if (frame instanceof CloseWebSocketFrame) {
        handshaker.close(ctx.channel(), 
            (CloseWebSocketFrame) frame.retain());
        return;
    }
    
    // 2. 处理Ping请求(心跳检测)
    if (frame instanceof PingWebSocketFrame) {
        ctx.channel().write(
            new PongWebSocketFrame(frame.content().retain())
        );
        return;
    }
    
    // 3. 只支持文本消息
    if (!(frame instanceof TextWebSocketFrame)) {
        throw new Exception("仅支持文本格式");
    }
    
    // 4. 解析消息
    String request = ((TextWebSocketFrame) frame).text();
    ClientMsgProtocol clientMsg = JSON.parseObject(request, 
        ClientMsgProtocol.class);
    
    // 5. 根据消息类型处理
    if (1 == clientMsg.getType()) {
        // 请求个人信息
        ctx.channel().writeAndFlush(
            MsgUtil.buildMsgOwner(ctx.channel().id().toString())
        );
    } else if (2 == clientMsg.getType()) {
        // 群发消息
        TextWebSocketFrame textFrame = MsgUtil.buildMsgAll(
            ctx.channel().id().toString(), clientMsg.getMsgInfo()
        );
        ChannelHandler.channelGroup.writeAndFlush(textFrame);
    }
}

WebSocket帧类型:

帧类型说明用途
TextWebSocketFrame文本消息聊天消息
BinaryWebSocketFrame二进制消息文件传输
PingWebSocketFramePing消息心跳检测
PongWebSocketFramePong消息心跳响应
CloseWebSocketFrame关闭消息关闭连接
5. ChannelGroup群发消息

ChannelHandler.java

public class ChannelHandler {
    // 用于存放所有在线用户的Channel
    public static ChannelGroup channelGroup = 
        new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
}

使用方式:

// 添加Channel
@Override
public void channelActive(ChannelHandlerContext ctx) {
    ChannelHandler.channelGroup.add(ctx.channel());
}

// 移除Channel
@Override
public void channelInactive(ChannelHandlerContext ctx) {
    ChannelHandler.channelGroup.remove(ctx.channel());
}

// 群发消息
TextWebSocketFrame textFrame = MsgUtil.buildMsgAll(channelId, msgInfo);
ChannelHandler.channelGroup.writeAndFlush(textFrame);

类比理解:

  • ChannelGroup:像一个微信群
  • Channel:群里的每个成员
  • writeAndFlush():群发消息给所有成员
6. 消息协议设计

ClientMsgProtocol.java - 客户端消息

public class ClientMsgProtocol {
    private int type;       // 1请求个人信息,2发送聊天信息
    private String msgInfo; // 消息内容
}

ServerMsgProtocol.java - 服务端消息

public class ServerMsgProtocol {
    private int type;             // 1自发信息、2群发消息
    private String channelId;     // 通信管道ID(用户标识)
    private String userHeadImg;   // 用户头像
    private String msgInfo;       // 消息内容
}

项目总结

核心技术:

  • ✅ WebSocket长连接:浏览器与服务器实时双向通信
  • ✅ HTTP握手升级:从HTTP协议升级到WebSocket
  • ✅ ChannelGroup:实现消息群发
  • ✅ 协议设计:清晰的客户端/服务端消息协议

适用场景:

  • 即时通讯(在线客服、企业聊天)
  • 实时推送(股票行情、新闻资讯)
  • 协同办公(在线文档、白板共享)
  • 游戏(多人在线游戏、实时对战)

netty案例,netty4.1中级拓展篇五《基于Netty搭建WebSocket,模仿微信聊天页面》 前言介绍 本章节我们模仿微信聊天页面,开发一个基于Netty搭建WebSocket通信案例。Netty的应用方面非常广;聊天、MQ、RPC、数据等等,在5G到来的时候更加需要大量数据传输,Netty的应用也会更加广阔。 1、这个案例使用SpringBoot+Netty+WebSocket搭建功能。 2、使用Netty提供的HttpServerCodec、HttpObjectAggregator、... 阅读详情

相关推荐

netty案例,netty4.1中级拓展篇一《Netty与SpringBoot整合》

前言介绍 在实际的开发中,我们需要对netty服务进行更多的操作,包括;获取它的状态信息、启动/停止、对客户端用户强制下线等等,为此我们需要把netty服务加入到web系统中,那么本章节介绍如何将Netty与SpringBoot整合。 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使...

bugstack虫洞栈 2642

Netty实战应用学习笔记-中级拓展篇(一)

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 1072

netty案例,netty4.1中级拓展篇七《Netty请求响应同步通信》

前言介绍 在我们实现开发RPC框架的时候,需要选择socket的通信方式。而我们知道一般情况下socket通信类似与qq聊天,发过去消息,什么时候回复都可以。但是我们RPC框架通信,从感觉上类似http调用,需要在一定时间内返回,否则就会发生超时断开。这里我们选择netty作为我们的socket框架,采用future方式进行通信。 Dubbo:国内最早开源的 RPC 框架,由阿里巴巴公司开发并于...

bugstack虫洞栈 2265

Netty实战应用学习笔记-中级拓展篇(六)

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 630

netty案例,netty4.1中级拓展篇二《Netty使用Protobuf传输数据》

前言介绍 在netty数据传输过程中可以有很多选择,比如;字符串、json、xml、java对象,但为了保证传输的数据具备;良好的通用性、方便的操作性和传输的高性能,我们可以选择protobuf作为我们的数据传输格式。目前protobuf可以支持;C++、C#、Dart、Go、Java、Python等,也可以在JS里使用。知识点;ProtobufDecoder、ProtobufEncoder、Pr...

bugstack虫洞栈 2080

netty案例,netty4.1中级拓展篇四《Netty传输文件、分片发送、断点续传》

前言介绍 1、在实际应用中我们经常使用到网盘服务,他们可以高效的上传下载较大文件。那么这些高性能文件传输服务,都需要实现的分片发送、断点续传功能。 2、在Java文件操作中有RandomAccessFile类,他可以支持文件的定位读取和写入,这样就满足了我们对文件分片的最基础需求。 3、Netty服务端启动后,可以向客户端发送文件传输指令;允许接收文件、控制读取位点、记录传输标记、文件接收完成。 ...

bugstack虫洞栈 3229

Dapper 快速上手指南:30 秒把数据库查询映射成 C 对象

Dapper 是 .NET 里一款轻量级 ORM / 对象映射器,核心就一件事:用最少的代码,把数据库查询结果映射成 C# 对象。它扩展 ADO.NET 的 `IDbConnection` 接口,不生成额外代码、不改变你的 SQL 写法,装好就能用。这篇 Dapper 教程带你从安装、配置到跑通第一次查询,顺带避开最常见的几个坑。 [![Dapper .NET 轻量 ORM 数据库映射项目主图]

gitblog_00439的博客 401

netty案例,netty4.1中级拓展篇三《Netty传输Java对象》

前言介绍 Netty在实际应用级开发中,有时候某些特定场景下会需要使用Java对象类型进行传输,但是如果使用Java本身序列化进行传输,那么对性能的损耗比较大。为此我们需要借助protostuff-core的工具包将对象以二进制形式传输并做编码解码处理。与直接使用protobuf二进制传输方式不同,这里不需要定义proto文件,而是需要实现对象类型编码解码器,用以传输自定义Java对象。 pro...

bugstack虫洞栈 2142

Netty实战应用学习笔记-中级拓展篇(十二)

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 1087

netty案例,netty4.1中级拓展篇八《Netty心跳服务与断线重连》

前言介绍 在我们使用netty中,需要监测服务是否稳定以及在网络异常链接断开时候可以自动重连。需要实现监听;f.addListener(new MyChannelFutureListener()) 环境准备 1、jdk1.8【jdk1.7以下只能部分支持netty】 2、Netty4.1.36.Final【netty3.x 4.x 5每次的变化较大,接口类名也随着变化】 代码示例 itstack-...

bugstack虫洞栈 2069

netty案例,netty4.1中级拓展篇十二《Netty流量整形数据流速率控制分析与实战》

作者:付政委 | 关注微信公众号:bugstack虫洞栈,获取专题案例源码 前言介绍 你是否使用过某盘,在前几年我们使用的时候速度飞快,上传下载嗖嗖嗖。但是近年来只要不办会员,速度慢的像蜗牛,当然人家也得赚钱我们能理解。那么这样的限速是怎么实现的呢,我们这个案例使用Netty的流量整形进行限速传输,测试过程中当你把流量整形功能去掉后你就是年费VIP。 流量整形(Traffic Shaping...

bugstack虫洞栈 3696

Netty实战应用学习笔记-中级拓展篇(九)

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 1063

Coze平台智能体开发实战:打造测试工程师的AI助手

智能体是具备特定身份和能力的AI实体,由大语言模型(LLM)驱动,并通过插件、知识库和工作流扩展其能力。明确的角色定位:可以设定特定身份和专业领域扩展能力:通过插件连接外部工具和服务记忆能力:通过知识库存储和检索专属信息流程化处理:通过工作流执行复杂多步任务通过Coze平台创建测试工程师智能体,可以显著提升测试效率和质量。明确的角色定位:聚焦测试工程师的实际需求丰富的知识库:提供准确的领域知识支持合适的工具集成:通过插件连接现有工具链持续迭代优化:根据反馈不断改进智能体行为自动化测试生成。

hogwarts_beibei的博客 1005

Netty实战应用学习笔记-中级拓展篇(八)

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 640

自偏置电流镜设计实例

自偏置电流镜设计实例 一、概述 ​ 众所周知,电流镜属于模拟电路设计中的一个基本模块,可为其他模块提供偏置电流,例如在放大器中提供偏置电流以形成尾电流源并确定直流偏置点。本文将会介绍一种自偏置的电流镜,从原理出发,并以0.18um的工艺进行设计和仿真。 二、原理 ​ 如图一所示的电路,也称之为Beta-multiply reference电路,其中M2的尺寸是M1的k倍。M3复制M4的电流,M2和M1的漏极电流相同,但是VGS并不相等。其中 VGS=2IμnCoxW/...

aonuanjiang的博客 1万+

OpenClaw Windows 最详细安装指南

Windows上养龙虾:OpenClaw完整安装教程+钉钉接入,助你养只大龙虾

weixin_43405859的博客 2215

Netty实战应用学习笔记-中级拓展篇(十三)

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 570

利用Virtuoso IC 618进行LDO稳定性分析与补偿设计

本文详细介绍了如何利用Virtuoso IC 618进行LDO稳定性分析与补偿设计。通过搭建仿真环境、运行STB分析诊断环路问题,并深入探讨密勒补偿、调零电阻等关键技术,帮助工程师在Virtuoso平台中高效完成LDO的稳定性优化与验证,确保芯片在各种工艺角下的鲁棒性。

weixin_29170327的博客 164

Netty实战应用学习笔记-中级拓展篇(七)

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 322

copilot基于 DeepSeek-R1 思路构建 VLA 自动驾驶强化学习系统

下面给出一个完整示例代码,结合 DeepSeek‑R1 的技术方法,实现一个端到端的 VLA(视觉+语言行动)自动驾驶深度强化学习系统。.2f。

ywfwyht的博客 776

SpringBoot系列之实现一个AI聊天助手

本文介绍了基于Spring Boot框架实现的AI聊天助手项目。该项目使用Spring Boot 3.2.3、Spring AI 1.0.0-M5等技术栈,集成DeepSeek-R1-Distill-Llama-8B模型实现智能对话功能。文章详细介绍了项目配置流程、运行方式和核心代码实现,包括ChatMessage模型类和服务类ChatService的关键功能,如消息处理、历史记录管理和AI响应获取等。读者可通过提供的GitHub链接获取完整代码,快速搭建自己的AI聊天应用。

Nicky's blog 1452

Netty 4.1 使用 Protobuf 传输数据:itstack-demo-netty 中级拓展篇二实战解析

本篇技术指南以 CodeGuide 开源仓库中 itstack-demo-netty 中级拓展篇二的完整案例为蓝本,讲解如何在 Netty 4.1 服务端与客户端之间使用 Google Protocol Buffers(Protobuf)作为数据传输格式,涵盖 `MsgInfo.proto` 协议定义、protoc 编译、`ProtobufDecoder` / `ProtobufEncoder`

gitblog_00156的博客 248

【2025最新版】间接平差——以水准网平差为例 (python详细过程版)

水准网间接平差的python代码实现。博客长期更新,本文最新更新时间为:2025年5月20日。

点云侠的博客 1702

Netty实战应用学习笔记-中级拓展篇(三)

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 306

【Docker】完美解决拉取镜像超时报错:ERROR: Get https://registry-1.docker.io/v2/

因为我们下载的镜像是外网的镜像资源,所以下载的速度会非常的慢,甚至大概率下载时会报错,所以需要我们配置一个国内的服务器镜像地址,国内服务器镜像地址有很多,这里咱们就说一下阿里镜像加速器的配置方法。

liu_chen_yang的博客 12万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: Netty实战应用学习笔记-中级拓展篇(四)
下一篇: Netty实战应用学习笔记-中级拓展篇(六)
不早睡不改名@
博客等级 码龄5年 536粉丝 306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值