場景:後端更新資料推送到客戶端(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(或長連線)變的很容易。 .js伺服器程式碼:
<script src="static/js/socket.io.js"></script>
建立好客戶端同Node.js伺服器的連線只是第一步,以下還需要建立Node.js伺服器與Java業務邏輯層的聯繫。有多少個客戶端請求,都從Node.js伺服器轉發至Tomcat;同樣,Tomcat推送過來的數據,也經由Node.js伺服器分發至各個客戶端。在 WebSocket連線與Socket連線都建立好之後,兩次連線彼此之間是屏蔽的。 Tomcat不知道是哪次WebSocket連線發送過來的數據,也不知道是哪個客戶端發來的資料。可以利用session id送到Tomcat來識別是哪一個客戶端,但本文採用的是另一個方法。這裡稱它為socketIO。 Node.js伺服器發送資料給Tomcat時帶上這個socket_id,再由Java部分進行一系列處理以後封裝好每個客戶端需要的不同資料一併返回,返回的資料裡要有與socket_id的對應關係。 ,Node.js伺服器收到Tomcat發送的資料時,透過前面提到的映射表由不同的socketIO分送到不同的客戶端。
var socket = io.connect('127.0.0.1:8181'); // 发送数据至服务器 socket.emit('fromWebClient', jsonData); // 从服务器接收数据 socket.on('pushToWebClient', function (data) { // do sth. });
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伺服器從Tomcat接收的伺服器數據分為兩種,一種是推送過來的數據,另一種是回應請求的數據,這裡統一處理推送過來的數據。
處理通訊時,Node.js傳送至Tomcat的資料是String格式,而從Tomcat接收的資料為Buffer物件(8進位),需要轉換為String之後再轉換為json傳送至客戶端。
本文只是給出一個這樣兩次連接的簡單例子,具體的業務中需要加入許多東西。既然在專案中引入了Node.js,就需要前端承擔更多的事情,例如對資料的處理、快取、甚至加入很多業務邏輯。
以上就是Node.js實作資料推送_node.js?1.1.2的內容,更多相關內容請關注PHP中文網(m.sbmmt.com)!
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_id webClientData['sid'] = socketIO.id; // 发送String类型的数据至Tomcat nodeServer.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); } });