日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

轮询、服务器发送事件与WebSocket

發布時間:2024/6/21 综合教程 24 生活家
生活随笔 收集整理的這篇文章主要介紹了 轮询、服务器发送事件与WebSocket 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

輪詢

傳統輪詢

傳統輪詢借助setInterval或者setTimeout,并結合Ajax技術的方式實現。

//1
//使用setInterval,每隔10s向服務器發送一次請求。
//存在的問題是:在網絡不穩定的情況下,無法保證請求以及服務器響應的順序。
setInterval(function() {
    $.getJSON("url-path")
    .done(function(data) {
        console.log(data);
    });
}, 10000);

//2
//使用setTimeout,在每一次的請求并收到響應后,發送下一次請求。
//解決的問題:保證了每次請求的先后順序。
//存在的問題:仍然無法保證每次請求的間隔時間。
function poll() {
    setTimeout(function() {
        $.getJSON("url-path")
        .done(function(data) {
            console.log(data);
            
            //發起下一次請求
            poll();
        });
    }, 1000);
}

缺點分析

每次都需要新發起一條http請求。

客戶端來說占用較多內存資源與請求資源,對服務器來說占用較多的內存資源與帶寬資源

補充:對TCP協議三次握手的理解。

請求(含SYN標記的數據包):客戶端-->Apache/nginx服務器-->php/java/...等后端程序
響應(含SYN-ACK標記的數據包):后端程序-->Apache/nginx服務器-->客戶端
確認收到(含ACK標記的數據包):客戶端-->Apache/nginx服務器-->后端程序

長輪詢

長輪詢與下文的服務器發送事件和WebSocket都需要服務器配合。

//服務器
//通過死循環,以資源的修改時間作為循環跳出條件。
//就是上文三次握手的服務器響應階段,被后端程序的死循環“hold”住。
//當請求的服務器資源的最后一次修改時間==不舊于==客戶端請求參數所攜帶資源的時間(Last-Modified)時,跳出循環,并返回數據。

//客戶端
function longPoll(_timeStamp) {
    let _timeStamp;
    $.get("url-path")
    .done(function(data) {
        try{
            let res = JSON.parse(data);
            console.log(res.msg);
        }catch(e) {}
    })
    .always(function() {
        setTimeout(function() {
            longPoll(_timeStamp || Date.now() / 1000);
        }, 10000); 
    });
}

缺點:服務器資源消耗大。

解決的問題:減少了http請求。

服務器發送事件(Server-sent Event)

該方法有幾大特征如下。

HTML5規范的組成部分。
服務器到客戶端的單向通信,不需要由客戶端發起。
以“事件流”的格式產生并推送。
其格式說明如下:

MIME類型:text/event-stream
event:事件類型
data:消息內容
id:用于設置客戶端EventSource對象的“last event ID string”內部屬性
retry:指定重新連接的時間

客戶端的處理方式: 借助EventSource對象實現。

let eventSource = new EventSource("/path/to/server");
eventSource.onmessage = (e) => {
    console.log(e.event, e.data);
};

//或者
eventSource.addEventListener("ping", function(e) {
   console.log(e.event, e.data); 
});

缺點:所有IE(包括Edge)都不支持該事件,可以通過EventSource Polyfill進行兼容處理(本質上仍然是輪詢)。

WebSocket

WebSocket有以下特征:

HTML5規范的組成部分,現在的版本是RFC6455。
實現原理較上文的幾種方式不同。
基于TCP協議。

看到這里,博客和知乎也有說基于HTTP協議的,列出網上的集合以及個人理解的集合圖。

知乎上Ovear的詳細解答:WebSocket借用HTTP協議來完成了部分握手操作。

//HTTP請求發送時,借助以下字段,通知服務器將協議切換到WebSocket。
Upgrade: websocket
Connection: Upgrade

個人的理解

繼續列舉它的特征
4. WebSocket是一個持久化的協議,相對于HTTP這種非持久的協議來說。
5. 服務器完成協議升級后,服務端可以主動推送信息給客戶端。
6. 需要socket程序實現以及額外的端口。

了解特征五之后,再思考一個問題,WebSocket與本文第二項#服務器發送事件有什么區別,與長輪詢呢?

先來看一下Websocket與長輪詢的區別。

WebSocket的流程

請求(第一次握手,同時將協議升級到WebSocket):客戶端-->Apache/nginx服務器-->后端處理程序
等待1(后端處理程序未通知信息):Apache/nginx服務器-->客戶端(保持連接狀態,使得服務器一直能夠了解客戶端的信息?)
等待2(后端處理程序通知信息):后端處理程序-->Apache/nginx服務器-->客戶端(通知客戶端更新數據)

長輪詢的流程

請求(含SYN標記的數據包):客戶端-->Apache/nginx服務器-->后端處理程序
響應(含SYN-ACK標記的數據包):后端程序“hold”住請求,待資源更新后才響應-->Apache/nginx服務器-->客戶端
確認收到(含ACK標記的數據包):客戶端-->Apache/nginx服務器-->后端程序
...重復N次

顯而易見的是,WebSocket協議免去了幾個重復的流程。有以下幾個優點:

不需要反復發送和確認http請求,免去服務器對http請求反復解析的工作。
資源未更新時,不需要通過后端代碼拖延響應的時機。WebSocket把與客戶端保持通信的任務交給了服務器,因此減少了本身處理速度就慢的程序的壓力。

與服務器發送事件的區別待補充

簡單WebSocket服務器實現代碼如下。
服務器(Node.js)

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ port: 8080 });

wss.on("connection", function(socket) {
    socket.on("message", function(ms) {
       console.log(msg); 
       socket.send("Nice to meet you!");
    });
});

瀏覽器作為客戶端

//WebSocket為客戶端JavaScript的原生對象
var ws = new WebSocket("ws://localhost:8080");
ws.onopen = function(event) {
    ws.send("Hello there");
}
ws.onmessage = function(event) {
    console.log(event.data);
}

本文是根據參考網址學習所得的筆記和心得。

總結

以上是生活随笔為你收集整理的轮询、服务器发送事件与WebSocket的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。