服務器端推送技術總結


最近在做前端頁面渲染的時候,有的組件需要跟隨數據的變化而實時的變化,例如:一個線上報名系統,總人數有一定限制,所以要實時的展現已經報名的人數,應該怎么實現呢?最基本解決思路如下:

    技術方案:

    1.Ajax輪詢

    2.Ajax長輪詢

    3.WebSocket

    Ajax輪詢

    實現簡單,利用XHR,通過setInterval定時向后端發送請求,優點是,實現非常簡單;缺點是會造成數據在一小段時間內不同步和大量無效的請求,增加后端處理壓力.

setInterval(function() {
    $.ajax({
        url: 'https://www.baidu.com/',
        success: function() {
            //success code
        }
    });
}, 3000);

  Ajax長輪詢

  在Ajax輪詢的基礎上做的一點改進,在后端數據沒有更新的時候不再返回空響應,而且后端一直保存連接,直到后端有數據變化,則相應請求並且關閉連接,前端收到數據,馬上再次向后端發起請求,並處理剛剛收到的數據.

function async() {
    $.ajax({
        url: 'http://api.3g.qq.com',
        success: function() {
            async();
            //success code
        }
    });
}

WebSocket

WebSocket是html5出來的東西(協議),也就是說http協議沒有變化,或者說沒關系,但http是不支持久鏈接的,WebSocket其實是一個新協議,跟http協議基本沒有關系,只是為了兼容現有瀏覽器的握手規范而已。

WebSocket通信協議包含兩個部分,一是開放性HTTP握手連接協商連接參數,二是二進制消息分幀機制(接收消息的文本和二進制數據傳輸)。它是一個獨立完善的協議,也可以在瀏覽器之外實現。

HTTP升級協商

WebSocket協議提供了很多強大的特性:基於消息的通信、自定義的二進制分幀層、子協議協商、可選的協議擴展,等等。即在交換數據之前,客戶端必須與服務器協商適當的參數以建立連接。

利用HTTP完成握手有幾個好處。首先,讓WebSockets與現有HTTP基礎設施兼容:WebSocket服務器可以運行在80和443 端口上,這通常是對客戶端唯一開放的端口。其次,讓我們可以重用並擴展HTTPUpgrade流,為其添加自定義的WebSocket首部,以完成協商。

請求頭信息

Connection:Upgrade Sec-WebSocket-Key:eDCPPyPQZq7PiwRcx8SPog== Sec-WebSocket-Version:13 Upgrade:websocket 

響應頭信息

HTTP/1.1 101 Switching Protocols Connection:Upgrade Sec-WebSocket-Accept:/ZVAP3n6XuqDUoDp416PYUO+ZJc= Upgrade:websocket 

最后,前述握手完成后,如果握手成功,該連接就可以用作雙向通信信道交換WebSocket消息。到此,客戶端與服務器之間不會再發生HTTP通信,一切由WebSocket 協議接管。

 具體使用方法,本文采用node.js中的Socket.IO來進行說明:

 1.服務端創建socket.io的實例

var app = require('express')();
var http = require('http').Server(app);
//創建實例
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendfile('index.html');
});

//監聽前端連接
io.on('connection', function(socket){
  console.log('a user connected');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

前端創建websocket連接:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>

2.數據傳輸

前端向后端發送數據:

 socket.emit('chat message', $('#m').val());

后端接收數據:

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    console.log('message: ' + msg);
  });
});

----------------------------------------------------------------------------------------------------------------------------------

后端向前端發送數據:

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});

前端接收數據:

 socket.on('chat message', function(msg){
    console.log(msg);
  });

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM