Node.js开发实战 实现数据推送功能
小作 2018-02-02 来源 :网络 阅读 691 评论 0

摘要:怎么用node.js实现数据推送的功能呢,这篇node.js开发教程会给你一个答案。

怎么用node.js实现数据推送的功能呢,这篇node.js开发教程会给你一个答案。

业务场景:后端更新数据推送到客户端(Java部分使用Tomcat服务器)。

后端推送数据的解决方案有很多,比如轮询、Comet、WebSocket。

1. 轮询对于后端来说开发成本最低,就是按照传统的方式处理Ajax请求并返回数据,在学校的时候实验室的项目一直都采用轮询,因为它最保险也最容易实现。但轮询带来的通信资源的浪费是无法忽视的,无论数据是否改变,都照常发送请求并响应,而且每次HTTP请求都带有很长的头部信息。

2. Comet的概念是长连接,客户端发送请求后,后端将连接保持下来,直到连接超时或后端返回数据时再重新建立连接,有效的将通信资源转移到了服务器上,实际消耗的是服务器资源。

3. WebSocket是HTML5提供的一种全双工通信技术,通过“握手”实现客户端与服务器之间的通信,实时性好,携带的头部也较小,目前支持的浏览器如下:

Node.js开发实战  实现数据推送功能

理想的情况是采取WebSocket与Comet结合的方式,对IE8等浏览器采取Comet方式,做降级处理。但是这样一来,后端需要实现两种处理请求的逻辑,即WebSocket与Comet。所以,本文加入Node.js,之所以这样做,是将处理WebSocket(或Comet)的逻辑转移到Node.js部分,不给后端“添麻烦”,因为在实际情况下,前端开发人员推动后端开发人员并不容易。Node.js作为浏览器与Java业务逻辑层通信的中间层,连接客户端与Tomcat,通过Socket与Tomcat进行通信(是Socket,不是WebSocket,后端需要实现Socket接口。

在客户端,WebSocket与Comet通过Socket.io实现,Socket.io会针对不同的浏览器版本或者不同客户端选择合适的实现方式(WebSocket, long pull..),Socket.io的引入让处理WebSocket(或长连接)变的很容易。Socket.io


客户端引入socket.io:

1 <script src="static/js/socket.io.js"></script>

客户端JavaScript代码:

1 var socket = io.connect('127.0.0.1:8181');2 // 发送数据至服务器3 socket.emit('fromWebClient', jsonData);4 // 从服务器接收数据5 socket.on('pushToWebClient', function (data) {6     // do sth.7 });


Node.js服务器代码:

 1 var http = require('http'), 2     app = http.createServer().listen('8181'), 3     io = require('socket.io').listen(app); 4 io.sockets.on('connection', function (socketIO) { 5     // 从客户端接收数据 6     socketIO.on('fromWebClient', function (webClientData) { 7         // do sth. 8     }); 9     // 客户端断开连接10     socketIO.on('disconnect', function () {11         console.log('DISCONNECTED FROM CLIENT');12     });        13     // 向客户端发送数据14     socketIO.emit('pushToWebClient', jsonData);    15 });

建立好客户端同Node.js服务器的连接只是第一步,下面还需要建立Node.js服务器与Java业务逻辑层的联系。这时,Node.js服务器则作为客户端,向Tomcat发送TCP连接请求。连接成功后,Node.js服务器和Tomcat建立了一条全双工的通道,而且是唯一的一条,不论有多少个客户端请求,都从Node.js服务器转发至Tomcat;同样,Tomcat推送过来的数据,也经由Node.js服务器分发至各个客户端。

这里存在一个问题,就是在WebSocket连接与Socket连接都建立好之后,两次连接彼此之间是屏蔽的。Tomcat不知道是哪次WebSocket连接发送过来的数据,也不知道是哪个客户端发来的数据。当然,Node.js可以利用session id发送至Tomcat来标识是哪一个客户端,但本文采用的是另外一种办法。

客户端同Node.js建立WebSocket连接时,每个连接都会包含一个实例,这里称它为socketIO。每个socketIO都有一个id属性用来唯一标识这个连接,这里称它为socket_id。利用socket_id,在Node.js服务器建立一个映射表,存储每一个socketIO与socket_id的映射关系。Node.js服务器发送数据给Tomcat时带上这个socket_id,再由Java部分进行一系列处理以后封装好每个客户端需要的不同数据一并返回,返回的数据里要有与socket_id的对应关系。这样,Node.js服务器收到Tomcat发来的数据时,通过前面提到的映射表由不同的socketIO分发至不同的客户端。


Node.js服务器代码:

1 var http = require('http'), 2     net = require('net'), 3     app = http.createServer().listen('8181'), 4     io = require('socket.io').listen(app), 5     nodeServer = new net.Socket(); 6 // 连接到Tomcat 7 nodeServer.connect(8007, '127.0.0.1', function() { 8     console.log('CONNECTED'); 9 });10 // 存储客户端的WebSocket连接实例11 var aSocket = {};12 // 同客户端建立连接13 io.sockets.on('connection', function (socketIO) {14     // 从客户端接收数据,然后发送至Tomcat15     socketIO.on('fromWebClient', function (webClientData) {        16         // 存储至映射表17         aSocket[socketIO.id] = socketIO;18         // 发送至Tomcat的数据中添加socket_id19         webClientData['sid'] = socketIO.id;        20         // 发送String类型的数据至Tomcat21         nodeServer.write(JSON.stringify(webClientData));        22     });23     // 客户端断开连接24     socketIO.on('disconnect', function () {25         console.log('DISCONNECTED FROM CLIENT');26     });    27 });28 29 // 从Tomcat接收数据30 nodeServer.on('data', function (data) {  31     var jsonData = JSON.parse(data.toString());    32     // 分发数据至客户端33     for (var i in jsonData.list) {34         aSocket[jsonData.list[i]['sid']].emit('pushToWebClient', jsonData.list[i].data);35     }36 });

上面的代码省略了一些逻辑,比如Node.js服务器从Tomcat接收的数据分为两种,一种是推送过来的数据,另外一种是响应请求的数据,这里统一处理推送过来的数据。

在处理通信时,Node.js发送至Tomcat的数据是String格式,而从Tomcat接收的数据为Buffer对象(8进制),需要转化为String之后再转化为json发送至客户端


本文只是给出一个这样两次连接的简单例子,具体的业务中需要加入许多东西。既然在项目中引入了Node.js,就需要前端承担更多的事情,比如对数据的处理、缓存、甚至加入很多业务逻辑。

总之,同学们,你想要的职坐标IT频道都能找到!


本文由 @小作 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程