
理想的情况是采取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:
<script src="static/js/socket.io.js"></script>
客户端JavaScript代码:
var socket = io.connect("127.0.0.1:8181"); // 发送数据至服务器socket.emit("fromWebClient", jsonData);// 从服务器接收数据 socket.on("pushToWebClient", function (data) {// do sth. });Node.js服务器代码: var http = require("http"), app = http.createServer().listen("8181"), io = require("socket.io").listen(app); io.sockets.on("connection", function (socketIO) { // 从客户端接收数据 socketIO.on("fromWebClient", function (webClientData) { // do sth. }); // 客户端断开连接 socketIO.on("disconnect", function () { console.log("DISCONNECTED FROM CLIENT"); }); // 向客户端发送数据 socketIO.emit("pushToWebClient", jsonData); });建立好客户端同Node.js服务器的连接只是第一步,下面还需要建立Node.js服务器与Java业务逻辑层的联系。这时,Node.js服务器则作为客户端,向Tomcat发送TCP连接请求。连接成功后,Node.js服务器和Tomcat建立了一条全双工的通道,而且是唯一的一条,不论有多少个客户端请求,都从Node.js服务器转发至Tomcat;同样,Tomcat推送过来的数据,也经由Node.js服务器分发至各个客户端。 var http = require("http"), net = require("net"), app = http.createServer().listen("8181"), io = require("socket.io").listen(app), nodeServer = new net.Socket(); // 连接到Tomcat nodeServer.connect(8007, "127.0.0.1", function() { console.log("CONNECTED"); });// 存储客户端的WebSocket连接实例 var aSocket = {}; // 同客户端建立连接 io.sockets.on("connection", function (socketIO) {// 从客户端接收数据,然后发送至Tomcat socketIO.on("fromWebClient", function (webClientData) {// 存储至映射表 aSocket[socketIO.id] = socketIO;// 发送至Tomcat的数据中添加socket_idwebClientData["sid"] = socketIO.id;// 发送String类型的数据至TomcatnodeServer.write(JSON.stringify(webClientData)); }); // 客户端断开连接 socketIO.on("disconnect", function () {console.log("DISCONNECTED FROM CLIENT"); });}); // 从Tomcat接收数据 nodeServer.on("data", function (data) {var jsonData = JSON.parse(data.toString()); // 分发数据至客户端 for (var i in jsonData.list) { aSocket[jsonData.list[i]["sid"]].emit("pushToWebClient", jsonData.list[i].data);} });上面的代码省略了一些逻辑,比如Node.js服务器从Tomcat接收的数据分为两种,一种是推送过来的数据,另外一种是响应请求的数据,这里统一处理推送过来的数据。