第五章 Netty进阶和实战学习笔记

本文详细介绍了Netty实现UDP单播和广播的原理及操作,包括Netty的UDP相关类如AddressedEnvelope、DatagramPacket和DatagramChannel的使用。接着探讨了服务器推送技术,如短轮询、Comet、基于AJAX的长轮询和SSE(服务器发送事件),对比了它们的优缺点。最后,文章提到了WebSocket通信,包括握手过程、STOMP子协议和WebSocket通信的实现。此外,还讨论了如何设计和实现基于Netty的高级通信服务,包括定义私有协议栈、跨节点通信和可靠性设计,如心跳机制、重连策略和重复登录保护等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、实现UDP单播和广播

UDP 这样的无连接协议中,并没有持久化连接这样的概念,并且每个消息(一个UDP数据报)都是一个单独的传输单元,此外UDP也没有TCP的握手机制。

通过类比,TCP连接就像打电话,其中一系列的有序消息将会在两个方向上流动,相反UDP则类似于往邮箱中投入一叠明信片;你无法知道它们将以何种顺序到达它们的目的地,或者它们是否所有的都能够到达它们的目的地。

UDP的这些方面可能会让你感觉到严重的局限性,但是它们也解释了为何它会比TCP快那么多,所有的握手以及消息管理机制的开销都已经被消除了;显然UDP很适合那些能够处理或者容忍消息丢失的应用程序,但可能不适合那些处理金融交易的应用程序。

本身作为无连接的不可靠的传输协议(适合频繁发送较小的数据包),他不会对数据包进行合并发送(也就没有Nagle算法之说了),他直接是一端发送什么数据,直接就发出去了,既然他不会对数据合并,每一个数据包都是完整的(数据+UDP头+IP头等等发一次数据封装一次)也就没有粘包一说了。

单播的传输模式,定义为发送消息给一个由唯一的地址所标识的单一的网络目的地。面向连接的协议和无连接协议都支持这种模式。

广播——传输到网络(或者子网)上的所有主机。

1、NettyUDP相关类

interface AddressedEnvelope<M, A extends SocketAddress>extends ReferenceCounted

定义一个消息,其包装了另一个消息并带有发送者和接收者地址。其中M是消息类型;A是地址类型

class DefaultAddressedEnvelope<M, A extends SocketAddress>implements AddressedEnvelope<M,A>提供了interface AddressedEnvelope的默认实现。class DatagramPacket extends DefaultAddressedEnvelope<ByteBuf, InetSocketAddress> implements ByteBufHolder扩展了DefaultAddressedEnvelope以使用ByteBuf作为消息数据容器,DatagramPacket是final类不能被继承,只能被使用。

通过content()来获取消息内容

通过sender();来获取发送者的消息

通过recipient();来获取接收者的消息。

interface DatagramChannel extends Channel扩展了Netty的Channel抽象以支持UDP的多播组管理。

class NioDatagramChannnel extends AbstractNioMessageChannel implements DatagramChannel定义了一个能够发送和接收Addressed-Envelope消息的Channel类型。

Netty的DatagramPacket是一个简单的消息容器,DatagramChannel实现用它来和远程节点通信。类似于在我们先前的类比中的明信片,它包含了接收者(和可选的发送者)的地址以及消息的有效负载本身。

2、UDP单播

参见模块netty-udp下的包com.chj.udp.unicast

3、UDP广播

参见模块netty-udp下的包com.chj.udp.broadcast

二、服务器推送技术-短轮询和Comet

服务器推送技术干嘛用?就是让用户在使用网络应用的时候,不需要一遍又一遍的去手动刷新就可以及时获得更新的信息。大家平时在上各种视频网站时,对视频节目进行欢乐的吐槽和评论,会看到各种弹幕,当然,他们是用flash技术实现的,对于我们没有用flash的应用,一样可以实现弹幕。又比如在股票网站,往往可以看到,各种股票信息的实时刷新,上面的这些都是基于服务器推送技术。

具体代码参见模块netty-comet

1、Ajax短轮询

就是用一个定时器不停的去网站上请求数据。

2、Comet

服务器推”是一种很早就存在的技术,以前在实现上主要是通过客户端的套接口,或是服务器端的远程调用。因为浏览器技术的发展比较缓慢,没有为“服务器推”的实现提供很好的支持,在纯浏览器的应用中很难有一个完善的方案去实现“服务器推”并用于商业程序。因为AJAX技术的普及,gmail等等在实现中使用了这些新技术;同时“服务器推”在现实应用中确实存在很多需求,称这种基于HTTP长连接、无须在

浏览器端安装插件的“服务器推”技术为“Comet”。

3、基于AJAX的长轮询

Spring mvc的控制层接收用户的请求之后,如果要采用异步处理,那么就要返回DeferedResult<>泛型对象,在调用完控制层之后,立即返回DeferedResult对象,此时驱动控制层的容器主线程,可以处理更多的请求。可以将DeferedResult对象作为真实响应数据的代理,而真实的数据是该对象的成员变量result,它可以是String类型,或者ModelAndView类型等。

业务处理完毕之后,要执行setResult方法,将真实的响应数据赋值到DeferedResult对象中,此时容器主线程会继续执行getResult方法,将真实数据响应到客户端。

### 关于 Netty进阶学习 Netty 是一款基于 Java NIO 开发的高性能网络框架,广泛应用于分布式系统中的通信模块开发。对于希望深入研究 Netty 的开发者来说,除了基础概念外,还需要了解其核心组件的工作原理以及如何优化性能。 #### FixedLengthFrameDecoder 使用说明 在 Netty 中,`FixedLengthFrameDecoder` 是一种用于处理固定长度消息帧的解码器[^3]。它能够自动将接收到的数据流分割成指定大小的消息块,从而简化了协议解析过程。以下是该类的一个简单应用实例: ```java import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.FixedLengthFrameDecoder; public class MyServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { // 假设每条消息都是固定的 10 字节 ch.pipeline().addLast(new FixedLengthFrameDecoder(10)); } } ``` 上述代码展示了如何通过 `FixedLengthFrameDecoder` 来设置一个固定长度的消息处理器。 #### 黑马程序员资源推荐 根据提供的参考资料,可以发现黑马程序员提供了丰富的 Java 学习路径实战项目指导[^1]。虽然具体提到的内容主要集中在支付系统的实现上,但它同样覆盖了许多高级主题,比如 Dubbo、Redis Spring Cloud 等技术栈[^2]。这些内容可能间接涉及到了 Netty 的实际应用场景及其配置技巧。 如果想要获取更详细的 Netty 进阶教程,则建议关注以下几个方面: - **源码分析**:理解 Netty 内部机制的最佳方法之一就是阅读官方文档并结合源码进行剖析。 - **案例实践**:尝试构建一些小型服务端程序来熟悉各种 Handler 的用途及链路管理方式。 - **社区交流**:加入相关论坛或者微信群组向其他资深工程师请教经验心得。 最后提醒一下各位同学,在学习过程中遇到困难时不要轻易放弃,多查阅资料并与同行讨论往往能带来意想不到的效果!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值