欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Node.js實(shí)現(xiàn)數(shù)據(jù)推送

 更新時(shí)間:2016年04月14日 14:11:35   投稿:lijiao  
這篇文章主要為大家詳細(xì)介紹了Node.js實(shí)現(xiàn)數(shù)據(jù)推送的相關(guān)資料,感興趣的小伙伴們可以參考一下

場(chǎng)景:后端更新數(shù)據(jù)推送到客戶端(Java部分使用Tomcat服務(wù)器)。

后端推送數(shù)據(jù)的解決方案有很多,比如輪詢、Comet、WebSocket。

1. 輪詢對(duì)于后端來(lái)說(shuō)開(kāi)發(fā)成本最低,就是按照傳統(tǒng)的方式處理Ajax請(qǐng)求并返回?cái)?shù)據(jù),在學(xué)校的時(shí)候?qū)嶒?yàn)室的項(xiàng)目一直都采用輪詢,因?yàn)樗畋kU(xiǎn)也最容易實(shí)現(xiàn)。但輪詢帶來(lái)的通信資源的浪費(fèi)是無(wú)法忽視的,無(wú)論數(shù)據(jù)是否改變,都照常發(fā)送請(qǐng)求并響應(yīng),而且每次HTTP請(qǐng)求都帶有很長(zhǎng)的頭部信息。

2. Comet的概念是長(zhǎng)連接,客戶端發(fā)送請(qǐng)求后,后端將連接保持下來(lái),直到連接超時(shí)或后端返回?cái)?shù)據(jù)時(shí)再重新建立連接,有效的將通信資源轉(zhuǎn)移到了服務(wù)器上,實(shí)際消耗的是服務(wù)器資源。

3. WebSocket是HTML5提供的一種全雙工通信技術(shù),通過(guò)“握手”實(shí)現(xiàn)客戶端與服務(wù)器之間的通信,實(shí)時(shí)性好,攜帶的頭部也較小,目前支持的瀏覽器如下:

理想的情況是采取WebSocket與Comet結(jié)合的方式,對(duì)IE8等瀏覽器采取Comet方式,做降級(jí)處理。但是這樣一來(lái),后端需要實(shí)現(xiàn)兩種處理請(qǐng)求的邏輯,即WebSocket與Comet。所以,本文加入Node.js,之所以這樣做,是將處理WebSocket(或Comet)的邏輯轉(zhuǎn)移到Node.js部分,不給后端“添麻煩”,因?yàn)樵趯?shí)際情況下,前端開(kāi)發(fā)人員推動(dòng)后端開(kāi)發(fā)人員并不容易。Node.js作為瀏覽器與Java業(yè)務(wù)邏輯層通信的中間層,連接客戶端與Tomcat,通過(guò)Socket與Tomcat進(jìn)行通信(是Socket,不是WebSocket,后端需要實(shí)現(xiàn)Socket接口。

在客戶端,WebSocket與Comet通過(guò)Socket.io實(shí)現(xiàn),Socket.io會(huì)針對(duì)不同的瀏覽器版本或者不同客戶端選擇合適的實(shí)現(xiàn)方式(WebSocket, long pull..),Socket.io的引入讓處理WebSocket(或長(zhǎng)連接)變的很容易。Socket.io

客戶端引入socket.io:

<script src="static/js/socket.io.js"></script>
客戶端JavaScript代碼:

 var socket = io.connect('127.0.0.1:8181');
 // 發(fā)送數(shù)據(jù)至服務(wù)器
socket.emit('fromWebClient', jsonData);
// 從服務(wù)器接收數(shù)據(jù)
 socket.on('pushToWebClient', function (data) {
  // do sth.
 });

Node.js服務(wù)器代碼:

 var http = require('http'),
   app = http.createServer().listen('8181'),
   io = require('socket.io').listen(app);
 io.sockets.on('connection', function (socketIO) {
   // 從客戶端接收數(shù)據(jù)
   socketIO.on('fromWebClient', function (webClientData) {
     // do sth.
   });
   // 客戶端斷開(kāi)連接
   socketIO.on('disconnect', function () {
     console.log('DISCONNECTED FROM CLIENT');
   });    
   // 向客戶端發(fā)送數(shù)據(jù)
   socketIO.emit('pushToWebClient', jsonData);  
 });

建立好客戶端同Node.js服務(wù)器的連接只是第一步,下面還需要建立Node.js服務(wù)器與Java業(yè)務(wù)邏輯層的聯(lián)系。這時(shí),Node.js服務(wù)器則作為客戶端,向Tomcat發(fā)送TCP連接請(qǐng)求。連接成功后,Node.js服務(wù)器和Tomcat建立了一條全雙工的通道,而且是唯一的一條,不論有多少個(gè)客戶端請(qǐng)求,都從Node.js服務(wù)器轉(zhuǎn)發(fā)至Tomcat;同樣,Tomcat推送過(guò)來(lái)的數(shù)據(jù),也經(jīng)由Node.js服務(wù)器分發(fā)至各個(gè)客戶端。

這里存在一個(gè)問(wèn)題,就是在WebSocket連接與Socket連接都建立好之后,兩次連接彼此之間是屏蔽的。Tomcat不知道是哪次WebSocket連接發(fā)送過(guò)來(lái)的數(shù)據(jù),也不知道是哪個(gè)客戶端發(fā)來(lái)的數(shù)據(jù)。當(dāng)然,Node.js可以利用session id發(fā)送至Tomcat來(lái)標(biāo)識(shí)是哪一個(gè)客戶端,但本文采用的是另外一種辦法。

客戶端同Node.js建立WebSocket連接時(shí),每個(gè)連接都會(huì)包含一個(gè)實(shí)例,這里稱它為socketIO。每個(gè)socketIO都有一個(gè)id屬性用來(lái)唯一標(biāo)識(shí)這個(gè)連接,這里稱它為socket_id。利用socket_id,在Node.js服務(wù)器建立一個(gè)映射表,存儲(chǔ)每一個(gè)socketIO與socket_id的映射關(guān)系。Node.js服務(wù)器發(fā)送數(shù)據(jù)給Tomcat時(shí)帶上這個(gè)socket_id,再由Java部分進(jìn)行一系列處理以后封裝好每個(gè)客戶端需要的不同數(shù)據(jù)一并返回,返回的數(shù)據(jù)里要有與socket_id的對(duì)應(yīng)關(guān)系。這樣,Node.js服務(wù)器收到Tomcat發(fā)來(lái)的數(shù)據(jù)時(shí),通過(guò)前面提到的映射表由不同的socketIO分發(fā)至不同的客戶端。

Node.js服務(wù)器代碼:

 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');
 });
// 存儲(chǔ)客戶端的WebSocket連接實(shí)例
 var aSocket = {};
 // 同客戶端建立連接
 io.sockets.on('connection', function (socketIO) {
  // 從客戶端接收數(shù)據(jù),然后發(fā)送至Tomcat
   socketIO.on('fromWebClient', function (webClientData) {    
    // 存儲(chǔ)至映射表
     aSocket[socketIO.id] = socketIO;
    // 發(fā)送至Tomcat的數(shù)據(jù)中添加socket_id
    webClientData['sid'] = socketIO.id;    
    // 發(fā)送String類型的數(shù)據(jù)至Tomcat
    nodeServer.write(JSON.stringify(webClientData));    
   });
   // 客戶端斷開(kāi)連接
   socketIO.on('disconnect', function () {
    console.log('DISCONNECTED FROM CLIENT');
   });  
});
 // 從Tomcat接收數(shù)據(jù)
 nodeServer.on('data', function (data) { 
   var jsonData = JSON.parse(data.toString());  
   // 分發(fā)數(shù)據(jù)至客戶端
   for (var i in jsonData.list) {
     aSocket[jsonData.list[i]['sid']].emit('pushToWebClient', jsonData.list[i].data);
  }
 });

上面的代碼省略了一些邏輯,比如Node.js服務(wù)器從Tomcat接收的數(shù)據(jù)分為兩種,一種是推送過(guò)來(lái)的數(shù)據(jù),另外一種是響應(yīng)請(qǐng)求的數(shù)據(jù),這里統(tǒng)一處理推送過(guò)來(lái)的數(shù)據(jù)。

在處理通信時(shí),Node.js發(fā)送至Tomcat的數(shù)據(jù)是String格式,而從Tomcat接收的數(shù)據(jù)為Buffer對(duì)象(8進(jìn)制),需要轉(zhuǎn)化為String之后再轉(zhuǎn)化為json發(fā)送至客戶端。

本文只是給出一個(gè)這樣兩次連接的簡(jiǎn)單例子,具體的業(yè)務(wù)中需要加入許多東西。既然在項(xiàng)目中引入了Node.js,就需要前端承擔(dān)更多的事情,比如對(duì)數(shù)據(jù)的處理、緩存、甚至加入很多業(yè)務(wù)邏輯。

相關(guān)文章

  • 詳解Node.js利用node-git-server快速搭建git服務(wù)器

    詳解Node.js利用node-git-server快速搭建git服務(wù)器

    本篇文章主要介紹了詳解Node.js利用node-git-server快速搭建git服務(wù)器,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-09-09
  • 如何將node服務(wù)打包成可執(zhí)行文件PKG

    如何將node服務(wù)打包成可執(zhí)行文件PKG

    這篇文章主要介紹了如何將node服務(wù)打包成可執(zhí)行文件PKG問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 關(guān)于在mongoose中填充外鍵的方法詳解

    關(guān)于在mongoose中填充外鍵的方法詳解

    在學(xué)習(xí)非關(guān)系型數(shù)據(jù)庫(kù)mongoDB,希望能夠完成數(shù)據(jù)庫(kù)的CRUD,采用的是JS做的后臺(tái),因此用到了mongoose,下面這篇文章主要給大家介紹了關(guān)于在mongoose中填充外鍵的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-08-08
  • 搭建pomelo 開(kāi)發(fā)環(huán)境

    搭建pomelo 開(kāi)發(fā)環(huán)境

    Pomelo是基于 Node.js 的高性能、分布式游戲服務(wù)器框架。它包括基礎(chǔ)的開(kāi)發(fā)框架和相關(guān)的擴(kuò)展組件(庫(kù)和工具包),可以幫助你省去游戲開(kāi)發(fā)枯燥中的重復(fù)勞動(dòng)和底層邏輯的開(kāi)發(fā)。Pomelo不但適用于游戲服務(wù)器開(kāi)發(fā),也可用于開(kāi)發(fā)高實(shí)時(shí) Web 應(yīng)用
    2014-06-06
  • npm?install報(bào)錯(cuò)unable?to?resolve?dependency?tree的解決辦法

    npm?install報(bào)錯(cuò)unable?to?resolve?dependency?tree的解決辦法

    在開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)使用npm安裝依賴包來(lái)加速開(kāi)發(fā),但是在執(zhí)行npm install命令時(shí),有時(shí)會(huì)遇到各種錯(cuò)誤,下面這篇文章主要給大家介紹了關(guān)于npm?install報(bào)錯(cuò)unable?to?resolve?dependency?tree的解決辦法,需要的朋友可以參考下
    2023-05-05
  • 詳解node中創(chuàng)建服務(wù)進(jìn)程

    詳解node中創(chuàng)建服務(wù)進(jìn)程

    本篇文章主要介紹了詳解node中創(chuàng)建服務(wù)進(jìn)程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • nodejs創(chuàng)建簡(jiǎn)易web服務(wù)器與文件讀寫(xiě)的實(shí)例

    nodejs創(chuàng)建簡(jiǎn)易web服務(wù)器與文件讀寫(xiě)的實(shí)例

    下面小編就為大家?guī)?lái)一篇node js系列課程-創(chuàng)建簡(jiǎn)易web服務(wù)器與文件讀寫(xiě)的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • 詳解nodejs異步I/O和事件循環(huán)

    詳解nodejs異步I/O和事件循環(huán)

    本篇文章主要介紹了nodejs異步I/O和事件循環(huán),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • windows系統(tǒng)下安裝npm(Node.js)方法教程

    windows系統(tǒng)下安裝npm(Node.js)方法教程

    在Windows環(huán)境下進(jìn)行Node.js的安裝并不是一件復(fù)雜的事情,但是在安裝過(guò)程中需要注意一些細(xì)節(jié),下面這篇文章主要給大家介紹了關(guān)于windows系統(tǒng)下安裝npm(Node.js)的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • Nodejs實(shí)現(xiàn)短信驗(yàn)證碼功能

    Nodejs實(shí)現(xiàn)短信驗(yàn)證碼功能

    使用Nodejs的開(kāi)發(fā)者愈來(lái)越多,基于Nodejs的后臺(tái)開(kāi)發(fā)也多了起來(lái),像短信驗(yàn)證碼、短信群發(fā)、國(guó)際短信這些需求,完全可以采用第三方接口來(lái)實(shí)現(xiàn),云片就提供了這樣的接口
    2017-02-02

最新評(píng)論