暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Web实时消息推送的7种实现方案(三)

zhangyfr 2025-07-07
100

MQTT

什么是 MQTT协议?
MQTT 全称(Message Queue Telemetry Transport):一种基于发布/订阅(publish/subscribe)模式的轻量级通讯协议,通过订阅相应的主题来获取消息,是物联网(Internet of Thing)中的一个标准传输协议。

该协议将消息的发布者(publisher)与订阅者(subscriber)进行分离,因此可以在不可靠的网络环境中,为远程连接的设备提供可靠的消息服务,使用方式与传统的MQ有点类似。
image.png
TCP协议位于传输层,MQTT 协议位于应用层,MQTT 协议构建于TCP/IP协议上,也就是说只要支持TCP/IP协议栈的地方,都可以使用MQTT协议。

为什么要用 MQTT协议?

MQTT协议为什么在物联网(IOT)中如此受偏爱?而不是其它协议,比如我们更为熟悉的 HTTP协议呢?

  • 首先HTTP协议它是一种同步协议,客户端请求后需要等待服务器的响应。而在物联网(IOT)环境中,设备会很受制于环境的影响,比如带宽低、网络延迟高、网络通信不稳定等,显然异步消息协议更为适合IOT应用程序。

  • HTTP是单向的,如果要获取消息客户端必须发起连接,而在物联网(IOT)应用程序中,设备或传感器往往都是客户端,这意味着它们无法被动地接收来自网络的命令。

  • 通常需要将一条命令或者消息,发送到网络上的所有设备上。HTTP要实现这样的功能不但很困难,而且成本极高。

具体的MQTT协议介绍和实践,这里我就不再赘述了,大家可以参考我之前的两篇文章,里边写的也都很详细了。

MQTT协议的介绍

我也没想到 springboot + rabbitmq 做智能家居,会这么简单

MQTT实现消息推送

未读消息(小红点),前端 与 RabbitMQ 实时消息推送实践,贼简单~

Websocket

websocket应该是大家都比较熟悉的一种实现消息推送的方式,上边我们在讲SSE的时候也和websocket进行过比较。

WebSocket是一种在TCP连接上进行全双工通信的协议,建立客户端和服务器之间的通信渠道。浏览器和服务器仅需一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

image.png

springboot整合websocket,先引入websocket相关的工具包,和SSE相比额外的开发成本。

<!-- 引入websocket --> <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-websocket</artifactId> </dependency>

服务端使用@ServerEndpoint注解标注当前类为一个websocket服务器,客户端可以通过ws://localhost:7777/webSocket/10086来连接到WebSocket服务器端。

@Component @Slf4j @ServerEndpoint("/websocket/{userId}") publicclass WebSocketServer {     //与某个客户端的连接会话,需要通过它来给客户端发送数据     private Session session;     privatestaticfinal CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>();     // 用来存在线连接数     privatestaticfinal Map<String, Session> sessionPool = new HashMap<String, Session>();     /**      * 链接成功调用的方法      */     @OnOpen     public void onOpen(Session session, @PathParam(value = "userId") String userId) {         try {             this.session = session;             webSockets.add(this);             sessionPool.put(userId, session);             log.info("websocket消息: 有新的连接,总数为:" + webSockets.size());         } catch (Exception e) {         }     }     /**      * 收到客户端消息后调用的方法      */     @OnMessage     public void onMessage(String message) {         log.info("websocket消息: 收到客户端消息:" + message);     }     /**      * 此为单点消息      */     public void sendOneMessage(String userId, String message) {         Session session = sessionPool.get(userId);         if (session != null && session.isOpen()) {             try {                 log.info("websocket消: 单点消息:" + message);                 session.getAsyncRemote().sendText(message);             } catch (Exception e) {                 e.printStackTrace();             }         }     } }

前端初始化打开WebSocket连接,并监听连接状态,接收服务端数据或向服务端发送数据。

<script>     var ws = new WebSocket('ws://localhost:7777/webSocket/10086');     // 获取连接状态     console.log('ws连接状态:' + ws.readyState);     //监听是否连接成功     ws.onopen = function () {         console.log('ws连接状态:' + ws.readyState);         //连接成功则发送一个数据         ws.send('test1');     }     // 接听服务器发回的信息并处理展示     ws.onmessage = function (data) {         console.log('接收到来自服务器的消息:');         console.log(data);         //完成通信后关闭WebSocket连接         ws.close();     }     // 监听连接关闭事件     ws.onclose = function () {         // 监听整个过程中websocket的状态         console.log('ws连接状态:' + ws.readyState);     }     // 监听并处理error事件     ws.onerror = function (error) {         console.log(error);     }     function sendMessage({         var content = $("#message").val();         $.ajax({             url'/socket/publish?userId=10086&message=' + content,             type'GET',             data: { "id""7777""content": content },             success: function (data) {                 console.log(data)             }         })     } </script>

页面初始化建立websocket连接,之后就可以进行双向通信了,效果还不错
image.png
image.png

自定义推送

上边我们给我出了6种方案的原理和代码实现,但在实际业务开发过程中,不能盲目的直接拿过来用,还是要结合自身系统业务的特点和实际场景来选择合适的方案。

推送最直接的方式就是使用第三推送平台,毕竟钱能解决的需求都不是问题 ,无需复杂的开发运维,直接可以使用,省时、省力、省心,像goEasy、极光推送都是很不错的三方服务商。

一般大型公司都有自研的消息推送平台,像我们本次实现的web站内信只是平台上的一个触点而已,短信、邮件、微信公 众号、小程序凡是可以触达到用户的渠道都可以接入进来。
image.png

消息推送系统内部是相当复杂的,诸如消息内容的维护审核、圈定推送人群、触达过滤拦截(推送的规则频次、时段、数量、黑白名单、关键词等等)、推送失败补偿非常多的模块,技术上涉及到大数据量、高并发的场景也很多。所以我们今天的实现方式在这个庞大的系统面前只是小打小闹。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论