redis主动向页面push数据

本文详细介绍了如何通过Node.js、Socket.io和Redis技术栈实现前端页面与服务端之间的实时数据推送功能。通过创建pubsub.js服务端脚本订阅Redis频道,与socket.io建立连接,实现在页面上实时展示由Redis发布的数据。

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

对于页面上定时刷新显示的数据,之前一直都是比较“传统”的思想——那就是“页面通过ajax请求后台,后台响应后把数据返回给前台展示,如此反复……”,而自己也从来没有过“服务端主动向页面推送数据”的概念。

现在需要用到redis的发布/订阅,页面“订阅”某一channel,服务端在某一channel“发布”内容。服务端发布后,客户端可以通过订阅实时将刚刚发布的内容展示出来。

说说我探索的解决过程吧。。从用tomcat的WebSocketServlet,但发现已经不推荐使用(废弃了,加上它必须依赖tomcat,并且前台订阅的逻辑也难以表达,所以不行;后来又想到用javax.websocket-api.jar的@ServerEndpoint,但是,还是卡住了。。因为也是难以体现redis的发布/订阅功能。

后来一直苦于用何种解决方案,这时,socket.io+redis+node.js实时聊天的例子让我眼前一亮。。

 

好了,说说我对nodejs的理解——Node是一个Javascript运行环境(runtime),就是Js的服务器,类似tomcat或weblogic是java代码的运行服务器一样。。安装nodejs之后,最新版已经带了npm,而npm是用于安装各种支持nodejs扩展的客户端的。比如你想要用到redis,就必须安装redis的nodejs客户端。把nodejs配好环境变量后,使用如下命令即可安装redis:

npm install redis

安装好后,它默认是在C:\Users\xxx\node_modules多一个redis的文件夹的,但如果你安装的nodejs不在C盘,最好是把刚刚安装的module拷贝至你安装包下的node_modules目录下。安装好后,就可以在Js中使用require('redis')了。

socket.io连接于browser和nodejs的http服务器之间,可用于二者之间同步数据。同样,它也需要通过npm命令安装。

 

解决过程如下:

编写pubsub.js作为前台页面订阅某一渠道的服务端(便与测试,我这里是把渠道写死的: var c = 'testchannel';):

 

var server = require('http').createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(1379);
 
var redis = require('redis');
var redisclient = redis.createClient();
 
var sub = function(c) {
    var c = 'testchannel';
    redisclient.subscribe(c, function(e) {
        console.log('subscribe channel : ' + c);
    });
}
sub();
 
console.log('Server running at http://127.0.0.1:1379/');
 
var io = require('socket.io')(server);
io.on('connection', function(socket) {
    redisclient.on('message', function(error, msg) {
        console.log('connection');
        console.log(msg);
        socket.emit('msgReceived', msg);        
    });
})

 

 

然后,定义用来显示订阅消息的前台页面:

 

<html>
<head>
<script src="F:\nodejs\node_modules\socket.io\node_modules\socket.io-client\socket.io.js"></script>
<script src="jquery-1.7.2.min.js"></script>

</head>
<body>
	<div style="width:100px; height:200px; border:1px solid red" id="show"></div>
	</script>hello world <script type="text/javascript"> 
	var div = $("#show");
	console.log("hello"); 
        var socket = io('http://localhost:1379'); 
	socket.on('connection', function() { 
		console.log('connection setup for socket.io') }); 
	socket.on('msgReceived', function(msg) {
		//alert(div.html());
		div.append(msg + "<br/>"); 
		//alert(msg);
		}) 
</script>
</body>
</html>

 页面中var socket = io('http://localhost:1379');一行是关键,它和pubsub.js中 listen(1379)里对应。表明位于本地的Nodejs服务器的1379端口,在pubsub.js里listen(1379)被监听了。

 

用任一浏览器(我这里是谷歌的),打开刚定义的前台页面。



 页面此时没内容,因为还未开启pubsub.js发起订阅请求。

OK,我们开始运行pubsub.js发起请求



 

接下来要用redis发布请求咯:

打开redis服务:



 

 再打开一客户端,向testchannel发布消息:



 

运行pubsub.js: node pubsub.js

可以看到:



 

开启一redis客户端,可看到订阅内容:



 

重点来了,页面也可显示订阅的内容:



 

同理,你在java中写发布到渠道testchannel的的代码,前台页面一样可以显示。

而你开启另外一个浏览器(比如搜狗),也是可以看到实时订阅的消息的:



 这说明,已经做到了redis主动向页面push数据,实时推送的效果。

总结:nodejs作为页面订阅的pubsub.js的运行服务端,socket.io则是类似websocket的功能,实现nodejs和浏览器之间交流的桥梁,是redis向页面推送数据的关键。另外注意nodejs用到redis和socket.io这2个module,必须要先用npm命令安装扩展。注意redis发布订阅思想在实时推送中的模型——前台页面订阅某一渠道的消息,而发布的话则是由redis来发布的。

 

### 系统间数据推送网关的实现或选择 在系统之间进行数据推送时,选择合适的数据推送网关解决方案是关键。以下是几种常见的实现方式和推荐方案: #### 1. **基于XMPP协议的推送网关** - XMPP(Extensible Messaging and Presence Protocol)是一种基于XML的开放协议,广泛用于即时通讯领域。利用XMPP协议可以构建一个灵活、可扩展的数据推送网关。 - **优势**: - 协议简单且易于扩展,适合需要自定义功能的场景。 - 支持持久连接,能够实现实时数据推送,避免了轮询带来的性能问题。 - 可以通过扩展协议来支持更多的数据类型,如文本、图片等。 - **应用场景**:适用于需要实时通信的应用,如消息通知、状态更新等。 #### 2. **基于WebSocket推送网关** - WebSocket 是一种全双工通信协议,能够在客户端和服务器之间建立持久连接,非常适合实时数据推送。 - **优势**: - 支持双向通信,延迟低,适合高并发场景。 - 可以与现有的微服务架构集成,实现横向扩展。 - 通过集群化部署,可以有效分担单个节点的压力,提升系统的稳定性和可靠性。 - **应用场景**:适用于大规模用户访问的实时应用,如在线聊天、实时游戏、股票行情等。 #### 3. **基于HTTP/2 Server Push推送机制** - HTTP/2 引入了Server Push功能,允许服务器主动向客户端推送资源,减少了请求往返的时间。 - **优势**: - 利用现有的HTTP协议栈,兼容性好,部署成本低。 - 适用于Web应用中的静态资源预加载,提升页面加载速度。 - **应用场景**:适用于Web前端优化,尤其是需要快速加载多个资源的场景。 #### 4. **基于MQTT的物联网推送网关** - MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布-订阅消息传输协议,专为低带宽、高延迟或不可靠网络环境设计。 - **优势**: - 低功耗,适合移动设备和物联网设备使用。 - 支持一对多的消息发布,简化了消息传递模型。 - 能够处理大量设备的连接,适合大规模物联网部署。 - **应用场景**:适用于智能家居、工业自动化、远程监控等物联网场景。 #### 5. **基于Kafka的流式数据推送** - Kafka 是一个分布式流处理平台,具备高吞吐量、持久化存储和水平扩展能力。 - **优势**: - 支持高吞吐量的数据流处理,适合大数据场景。 - 提供持久化存储,确保数据不会丢失。 - 可以与其他大数据工具(如Spark、Flink)无缝集成,构建端到端的数据管道。 - **应用场景**:适用于日志收集、事件溯源、实时数据分析等场景。 --- ### 推荐方案 #### **1. XMPP + WebSocket 混合架构** - 结合XMPP的灵活性和WebSocket的高性能,构建一个混合架构的推送网关。 - XMPP用于处理复杂的业务逻辑和消息路由,而WebSocket则负责高效的实时通信。 - 这种架构可以在保证灵活性的同时,提供良好的性能表现,适合中大型企业级应用。 #### **2. Kafka + 微服务架构** - 使用Kafka作为底层的消息队列,结合微服务架构,构建一个可扩展性强的数据推送系统。 - Kafka负责数据的缓冲和分发,微服务负责具体的业务处理。 - 这种架构适合需要处理海量数据的场景,且具备良好的容错能力和扩展性。 #### **3. MQTT + 边缘计算** - 在物联网场景中,结合MQTT协议和边缘计算技术,构建一个低延迟、低功耗的推送网关。 - 边缘计算可以在本地处理部分数据,减少对中心服务器的依赖,提升响应速度。 - 这种架构适合智能硬件、工业控制等需要快速响应的场景。 --- ### 实现方式 #### **1. 单机部署** - 对于小型项目或测试环境,可以直接在一台服务器上部署推送网关。 - 优点是配置简单、维护方便,但缺点是性能有限,难以应对高并发请求。 #### **2. 集群部署** - 对于中大型项目,建议采用集群部署的方式,将多个节点组成一个负载均衡组。 - 通过负载均衡器(如Nginx、HAProxy)将请求分发到不同的节点,提升系统的可用性和扩展性。 - 同时,可以结合数据库或缓存(如Redis)来管理会话状态和消息队列。 #### **3. 容器化部署** - 使用Docker或Kubernetes等容器化技术,将推送网关部署为容器服务。 - 容器化部署具有更高的灵活性和可移植性,便于快速扩容和故障恢复。 - 可以结合CI/CD流程实现自动化部署和持续集成。 #### **4. 云原生架构** - 如果预算充足,可以选择云服务商提供的推送服务(如AWS SNS、阿里云MNS等)。 - 这些服务通常已经集成了高可用、自动扩缩容等功能,开发者只需关注业务逻辑即可。 - 云原生架构适合需要快速上线、降低运维成本的企业。 --- ### 示例代码(WebSocket推送) 以下是一个简单的WebSocket推送示例,展示了如何在Node.js环境中实现基本的WebSocket服务器: ```javascript const WebSocket = require('ws'); // 创建WebSocket服务器 const wss = new WebSocket.Server({ port: 8080 }); // 监听连接事件 wss.on('connection', (ws) => { console.log('Client connected.'); // 监听客户端发送的消息 ws.on('message', (message) => { console.log(`Received message: ${message}`); // 将消息广播给所有连接的客户端 wss.clients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { client.send(message); } }); }); // 监听连接关闭事件 ws.on('close', () => { console.log('Client disconnected.'); }); }); console.log('WebSocket server is running on ws://localhost:8080'); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值