业务场景:后端更新数据推送到客户端(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实现数据推送的更多相关文章

  1. 基于Node.js的实时推送 juggernaut

    基于Node.js的实时推送 juggernaut Juggernaut 基于 Node.js 构建.为浏览器和服务器端提供一个实时的连接,可在客户端和服务器端进行数据的实时推送,适合多角色游戏.聊天 ...

  2. node.js Websocket消息推送---GoEasy

    Goeasy, 它是一款第三方推送服务平台,使用它的API可以轻松搞定实时推送!个人感觉goeasy推送更稳定,推送 速度快,代码简单易懂上手快 浏览器兼容性:GoEasy推送 支持websocket ...

  3. javascript之数据推送

    我们使用ajax与后台服务进行交互,常常是通过触发事件来单次交互,但对于有些web应用来说,需要前台与后台保持长连接,前端不定时地接收后台推送的数据信息, 例如:股票行情分析.聊天室和网页在线游戏等. ...

  4. 理解HTML5数据推送应用开发问题

    一.数据推送 SSE是一种允许服务端向客户端推送新数据(通常称作数据推送)的HTML5技术.那么,究竟什么是数据推送?它与我们可能用过的其他技术有什么不同呢? 让我先来回答什么不是数据推送.数据推送有 ...

  5. 实时数据推送webSocket

    实时数据推送 在Web或移动项目中,服务器向客户端实时推送消息是一种常见的业务需求. 实现方式 Polling:轮询(俗称“拉”),即定期重新请求数据. Long-Polling:长轮询,是 Poll ...

  6. C# ASP.NET MVC 之 SignalR 学习 实时数据推送显示 配合 Echarts 推送实时图表

    本文主要是我在刚开始学习 SignalR 的技术总结,网上找的学习方法和例子大多只是翻译了官方给的一个例子,并没有给出其他一些经典情况的示例,所以才有了本文总结,我在实现推送简单的数据后,就想到了如何 ...

  7. 基于Web的数据推送技术(转)

    基于Web的数据推送技术 对于实时性数据显示要求比较高的系统,比如竞价,股票行情,实时聊天等,我们的解决方案有以下几种.1. HTTP请求发送模式,一般可以基于ajax的请求,比如每3秒一次访问下服务 ...

  8. HTML5支持服务器发送事件(Server-Sent Events)-单向消息传递数据推送(C#示例)

    传统的WEB应用程序通信时的简单时序图: 现在Web App中,大都有Ajax,是这样子: HTML5有一个Server-Sent Events(SSE)功能,允许服务端推送数据到客户端.(通常叫数据 ...

  9. SSE技术详解:使用 HTTP 做服务端数据推送应用的技术

    SSE ( Server-sent Events )是 WebSocket 的一种轻量代替方案,使用 HTTP 协议. 严格地说,HTTP 协议是没有办法做服务器推送的,但是当服务器向客户端声明接下来 ...

随机推荐

  1. eclipse选中变量,相同变量高亮。

    选择Windows->Preferences->Java->Editor->Mark Occurrences,全部选择并保存. 如下图:

  2. 07.常用的SQL语句

    常用SQL语句,仿照着写(只改动字段和表名,库名) 查看数据库引擎                SHOW ENGINES;(默认InnoDB) 用数据库生成UUID            selec ...

  3. Servlet&jsp基础:第四部分

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  4. [Effective Java]第十一章 序列化

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. C# 文件流相关操作

    二进制转换成图片: MemoryStream ms = new MemoryStream(bytes); ms.Position = ; Image img = Image.FromStream(ms ...

  6. Codeforces Round #257 (Div. 2) A题

    A. Jzzhu and Children time limit per test 1 second memory limit per test 256 megabytes input standar ...

  7. Visual C#两分钟搭建BHO IE钩子(转)

    摘自:http://www.cnblogs.com/mvc2014/p/3776054.html 微软在1997年正式推出Browser Helper Object (BHO), 使程序员能够更好的对 ...

  8. scala中如何编写自定义的流程控制结构

    scala是一种函数式编程风格的语言,除了常见的if......else  ,for ,while等传统的流程控制结构,也可以自定义流程控制的控制结构. 再了解scala如何实现编写新的流程结构,我们 ...

  9. 2dx中文乱码问题

    我们的代码里面有一个bug 为了跟之前兼容的策划导表工具兼容 导表工具导出的excel全部都是ansi的 为了兼容就只能手动改成utf 8 无bom格式 后来策划嫌烦了 就让在程序段处理这个 研究了好 ...

  10. iOS - Swift Swift 语言新特性

    1.Swift 2.0 带来哪些新变化 常规变化: 1.OS X 10.11.iOS 9 和 watchOS 2 SDK 采纳了一些 Objective-C 的特性用来提高 Swift 的编程体验, ...