使用Node.js实现数据推送
业务场景:后端更新数据推送到客户端(Java部分使用Tomcat服务器)。
后端推送数据的解决方案有很多,比如轮询、Comet、WebSocket。
1. 轮询对于后端来说开发成本最低,就是按照传统的方式处理Ajax请求并返回数据,在学校的时候实验室的项目一直都采用轮询,因为它最保险也最容易实现。但轮询带来的通信资源的浪费是无法忽视的,无论数据是否改变,都照常发送请求并响应,而且每次HTTP请求都带有很长的头部信息。
2. Comet的概念是长连接,客户端发送请求后,后端将连接保持下来,直到连接超时或后端返回数据时再重新建立连接,有效的将通信资源转移到了服务器上,实际消耗的是服务器资源。
3. WebSocket是HTML5提供的一种全双工通信技术,通过“握手”实现客户端与服务器之间的通信,实时性好,携带的头部也较小,目前支持的浏览器如下:

理想的情况是采取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 // 从客户端接收数据,然后发送至Tomcat
15 socketIO.on('fromWebClient', function (webClientData) {
16 // 存储至映射表
17 aSocket[socketIO.id] = socketIO;
18 // 发送至Tomcat的数据中添加socket_id
19 webClientData['sid'] = socketIO.id;
20 // 发送String类型的数据至Tomcat
21 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,就需要前端承担更多的事情,比如对数据的处理、缓存、甚至加入很多业务逻辑。
使用Node.js实现数据推送的更多相关文章
- 基于Node.js的实时推送 juggernaut
基于Node.js的实时推送 juggernaut Juggernaut 基于 Node.js 构建.为浏览器和服务器端提供一个实时的连接,可在客户端和服务器端进行数据的实时推送,适合多角色游戏.聊天 ...
- node.js Websocket消息推送---GoEasy
Goeasy, 它是一款第三方推送服务平台,使用它的API可以轻松搞定实时推送!个人感觉goeasy推送更稳定,推送 速度快,代码简单易懂上手快 浏览器兼容性:GoEasy推送 支持websocket ...
- javascript之数据推送
我们使用ajax与后台服务进行交互,常常是通过触发事件来单次交互,但对于有些web应用来说,需要前台与后台保持长连接,前端不定时地接收后台推送的数据信息, 例如:股票行情分析.聊天室和网页在线游戏等. ...
- 理解HTML5数据推送应用开发问题
一.数据推送 SSE是一种允许服务端向客户端推送新数据(通常称作数据推送)的HTML5技术.那么,究竟什么是数据推送?它与我们可能用过的其他技术有什么不同呢? 让我先来回答什么不是数据推送.数据推送有 ...
- 实时数据推送webSocket
实时数据推送 在Web或移动项目中,服务器向客户端实时推送消息是一种常见的业务需求. 实现方式 Polling:轮询(俗称“拉”),即定期重新请求数据. Long-Polling:长轮询,是 Poll ...
- C# ASP.NET MVC 之 SignalR 学习 实时数据推送显示 配合 Echarts 推送实时图表
本文主要是我在刚开始学习 SignalR 的技术总结,网上找的学习方法和例子大多只是翻译了官方给的一个例子,并没有给出其他一些经典情况的示例,所以才有了本文总结,我在实现推送简单的数据后,就想到了如何 ...
- 基于Web的数据推送技术(转)
基于Web的数据推送技术 对于实时性数据显示要求比较高的系统,比如竞价,股票行情,实时聊天等,我们的解决方案有以下几种.1. HTTP请求发送模式,一般可以基于ajax的请求,比如每3秒一次访问下服务 ...
- HTML5支持服务器发送事件(Server-Sent Events)-单向消息传递数据推送(C#示例)
传统的WEB应用程序通信时的简单时序图: 现在Web App中,大都有Ajax,是这样子: HTML5有一个Server-Sent Events(SSE)功能,允许服务端推送数据到客户端.(通常叫数据 ...
- SSE技术详解:使用 HTTP 做服务端数据推送应用的技术
SSE ( Server-sent Events )是 WebSocket 的一种轻量代替方案,使用 HTTP 协议. 严格地说,HTTP 协议是没有办法做服务器推送的,但是当服务器向客户端声明接下来 ...
随机推荐
- Download file using libcurl in C/C++
http://stackoverflow.com/questions/1636333/download-file-using-libcurl-in-c-c #include <stdio.h&g ...
- HDU 5835 Danganronpa(弹丸论破)
Danganronpa(弹丸论破) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- NS_ASSUME_NONNULL_BEGIN,NS_ASSUME_NONNULL_END
Nonnull区域设置(Audited Regions) 如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事.苹果为了减轻我们的工作量,专门提供了两个宏:NS_AS ...
- java中类名.class、实例.getclass()区别
import java.util.HashSet; import java.util.Iterator; /** * Created by GOD on 2016/1/23. * Class对象的生成 ...
- phpcms 在后台增加了一个模型的话,在数据库中就会相应的增加数据库表
在phpcms后台管理系统中,我们如果增加一个新的模型的话,例如名为:测试模型,英文名:test 在添加完成后,我们在数据库中发现增加了两个数据表:v9_test,v9_test_data;
- 转 谈谈android反编译和防止反编译的方法
谈谈android反编译和防止反编译的方法 android基于java的,而java反编译工具很强悍,所以对正常apk应用程序基本上可以做到100%反编译还原. 因此开发人员如果不准备开源自己的项 ...
- HDU5869树状数组+gcd预处理
比赛的时候知道用树状数组,但有点乱不知道怎么处理. 统计不同的gcd的个数其实就是用树状数组统计区间内不同的数的模板题啊... 复杂度O(nlogn) #include <bits/stdc++ ...
- linux虚拟机安装
1.真实机第一次安装必须先搞f2进入boot从光盘启动,虚拟机不用 进入的时候五个选项Install or upgrade an existing system:安装或升级现有系统Install sy ...
- poj2451Uyuw's Concert(半平面交)
链接 逆时针给出线段,如果模板是顺时针的修改下系数的符号进行平面交即可. #include <iostream> #include<cstdio> #include<cs ...
- Ubuntu Server14.04 32位安装odoo8.0简单方法
一.wget -O - https://nightly.odoo.com/odoo.key | apt-key add - 二.echo "deb http://nightly.odoo.c ...