搜尋
首頁web前端js教程JavaScript中一些web通訊知識點總結(分享)

JavaScript中一些web通訊知識點總結(分享)

web通信,一個特別大的topic,涉及面也是很廣的。因最近學習了 javascript 中一些 web 通訊知識,在這裡總結下。

一、前言

1、comet技術

瀏覽器作為 Web 應用的前台,自身的處理功能比較有限。瀏覽器的發展需要客戶端升級軟體,同時由於客戶端瀏覽器軟體的多樣性,在某種意義上,也影響了瀏覽器新技術的推廣。

在 Web 應用程式中,瀏覽器的主要工作是發送請求、解析伺服器傳回的資訊以不同的風格顯示。 AJAX 是瀏覽器技術發展的成果,透過在瀏覽器端發送非同步請求,提高了單一使用者操作的回應性。

但 Web 本質上是一個多用戶的系統,對任何使用者來說,可以認為伺服器是另一個使用者。現有 AJAX 技術的發展並不能解決在一個多用戶的 Web 應用中,將更新的資訊即時傳送給客戶端,從而用戶可能在「過時」的資訊下進行操作。而 AJAX 的應用程式又讓後台資料更新更加頻繁成為可能。

隨著網路的發展,web 應用程式層出不窮,也不乏各種網站監控、即時報價、即時通訊系統,為了讓使用者得到更好的體驗,伺服器需要頻繁的向客戶端推送資訊。

開發者一般會採用基於 AJAX 的長輪詢方式或基於 iframe 和 htmlfile 的流方式處理。當然有些程式需要在客戶端安裝各種外掛程式( Java applet 或 Flash )來支援效能比較良好的「推」資訊。

2. HTTP協定中的長、短連線

短連線的操作步驟是:建立連線-資料傳輸-關閉連線...建立連線-資料傳輸—關閉連線

長連線的操作步驟是:建立連線-資料傳輸...(保持連線)...資料傳輸-關閉連線

長連線與短連線的不同主要在於client和server採取的關閉策略不同。短連接在建立連接以後只進行一次數據傳輸就關閉連接,而長連接在建立連接以後會進行多次數據數據傳輸直至關閉連接(長連接中關閉連接通過Connection:closed頭部字段)。

二、web 通訊

首先要搞清楚,xhr 的 readystate 各種狀態。

JavaScript中一些web通訊知識點總結(分享)

1.輪詢

#輪詢是一種「拉」取訊息的工作模式。設定定時器,定時詢問伺服器是否有訊息,每次建立連線傳輸資料後,連結會關閉。

前端實作:

var polling = function(url, type, data){
    var xhr = new XMLHttpRequest(), 
        type = type || "GET",
        data = data || null;

    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4) {
            receive(xhr.responseText);
            xhr.onreadystatechange = null;
        }
    };

    xhr.open(type, url, true);
    //IE的ActiveXObject("Microsoft.XMLHTTP")支持GET方法发送数据,
    //其它浏览器不支持,已测试验证
    xhr.send(type == "GET" ? null : data);
};

var timer = setInterval(function(){
    polling();
}, 1000);

在輪詢的過程中,如果因為網路原因,導致上一個xhr 物件還沒傳輸完畢,計時器已經開始了下一個詢問,上一次的傳輸是否還會在隊列中,這個問題我沒去研究。如果有興趣可以自己寫一個ajax的請求管理佇列。

2.長輪詢(long-polling)

長輪詢其實也沒啥特殊的地方,就是在xhr物件關閉連接的時候馬上又給他接上~ 看碼:

var longPoll = function(type, url){
    var xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function(){
        // 状态为 4,数据传输完毕,重新连接
        if(xhr.readyState == 4) {
            receive(xhr.responseText);
            xhr.onreadystatechange = null;

            longPoll(type, url);
        }
    };

    xhr.open(type, url, true);
    xhr.send();
}

只要伺服器斷開連接,客戶端馬上連接,不讓他有一刻的休息時間,這就是長輪詢。

3.資料流

資料流方式,在建立的連線中斷之前,也就是readystate 狀態為3 的時候接受數據,但是麻煩的事情也在這裡,因為資料正在傳輸,你拿到的xhr.response 可能就是半截數據,最好定義一個數據傳輸的協議,例如前2個位元組表示字串的長度,然後你只取得這個長度的內容,接著改變遊標的位置。

假如資料格式為: data splitChar   data為資料內容,splitChar為資料結束標誌(長度為1)。那麼傳輸的數據內容為data splitChar data splitChar data splitChar...

var dataStream = function(type, url){
    var xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function(){

        // 状态为 3,数据接收中
        if(xhr.readyState == 3) {
            var i, l, s;

            s = xhr.response; //读取数据
            l = s.length;     //获取数据长度

            //从游标位置开始获取数据,并用分割数据
            s = s.slice(p, l - 1).split(splitChar);

            //循环并操作数据
            for(i in s) if(s[i])  deal(s[i]);

            p = l;  //更新游标位置

        }

        // 状态为 4,数据传输完毕,重新连接
        if(xhr.readyState == 4) {
            xhr.onreadystatechange = null;

            dataStream(type, url);
        }
    };

    xhr.open(type, url, true);
    xhr.send();
};

這個代碼寫的是存在問題的,當readystate為3的時候可以獲取數據,但是這時獲取的數據可能只是整體數據的一部分,那後半截就拿不到了。

readystate在資料傳輸完畢之前是不會改變的,也就是說他並不會繼續接受剩下的資料。我們可以定時去監聽readystate,這個下面的範例可以看到。

這樣的處理不算複雜,但是有問題。上面的輪詢和長輪詢是所有瀏覽器都支援的,所以我就沒有寫相容IE的程式碼,但是這裡,低版本IE不允許在readystate為3的時候讀取數據,所以我們必須採用其他的方式來實現。

在ajax還沒有進入web專題之前,我們已經擁有了一個法寶,那就是iframe,利用iframe照樣可以異步獲取數據,對於低版本IE可以使用iframe來接受數據流。

if(isIE){
    var dataStream = function(url){
        var ifr = document.createElement("iframe"), doc, timer;

        ifr.src = url;
        document.body.appendChild(ifr);

        doc = ifr.contentWindow.document;

        timer = setInterval(function(){

            if(ifr.readyState == "interactive"){
                // 处理数据,同上
            }

            // 重新建立链接
            if(ifr.readyState == "complete"){
                clearInterval(timer);

                dataStream(url);
            }
        }, 16);
    };
};

定时去监听iframe的readystate的变化,从而获取数据流,不过,上面的处理方式还是存在问题。数据流实现“服务器推”数据的原理是什么呢,就是文档(数据)还没有加载完,这个时候浏览器的工作就是去服务器拿数据完成文档(数据)加载。

所以上述利用iframe的方式获取数据,会使浏览器一直处于加载状态,title上的那个圈圈一直在转动,鼠标的状态也是loading,这看着是相当不爽的。

幸好,IE提供了HTMLFile对象,这个对象就相当于一个内存中的Document对象,它会解析文档。所以我们创建一个HTMLFile对象,在里面放置一个IFRAME来连接服务器。这样,各种浏览器就都支持了。

if(isIE){
    var dataStream = function(url){
        var doc = new ActiveXObject("HTMLFile"), 
            ifr = doc.createElement("iframe"), 
            timer, d;

        doc.write("
");         ifr.src = url;         doc.body.appendChild(ifr);         d = ifr.contentWindow.document;         timer = setInterval(function(){             if(d.readyState == "interactive"){                 // 处理数据,同上             }             // 重新建立链接             if(d.readyState == "complete"){                 clearInterval(timer);                 dataStream(url);             }         }, 16);     }; };

4.websocket

websocket是前端一个神器,ajax用了这么久了,相关技术也是很成熟,不过要实现个数据的拉取确实十分不易,从上面的代码中也看到了,各种兼容性问题,各种细节处理问题。

var ws = new WebSocket("ws://www.example.com:8888");

ws.onopen = function(evt){};
ws.onmessage = function(evt){
    deal(evt.data);
};
ws.onclose  = function(evt){};

//ws.close();

新建一个WebSocket实例,一切就OK了,ws:// 是websocket的连接协议,8888为端口号码。onmessage中提供了data这个属性,相当方便

5.EventSource

HTML5中提供的EventSource这玩意儿,这是无比简洁的服务器推送信息的接受函数。

new EventSource("test.php").onmessage=function(evt){
    console.log(evt.data);
};

简洁程度和websocket是一样的啦,只是这里有一个需要注意的地方,test.php输出的数据流应该是特殊的MIME类型,要求是"text/event-stream",如果不设置的话,你试试~ (直接抛出异常)

6.ActionScript

情非得已就别考虑这第六种方式了,虽说兼容性最好,要是不懂as,出了点bug你也不会调试。

具体实现方法:在 HTML 页面中内嵌入一个使用了 XMLSocket 类的 Flash 程序。JavaScript 通过调用此 Flash 程序提供的套接口接口与服务器端的套接口进行通信。JavaScript 在收到服务器端以 XML 格式传送的信息后可以很容易地控制 HTML 页面的内容显示。

7.Java Applet套接口

三、后端处理方式

本文主要是总结Javascript的各种通讯方式,后端配合node来处理,应该是挺给力的。

var conns = new Array();

var ws = require("websocket-server");
var server = ws.createServer();

server.addListener("connection", function(connection){
  console.log("Connection request on Websocket-Server");
  conns.push(connection);
  connection.addListener('message',function(msg){
        console.log(msg);
        for(var i=0; i<conns.length server.listen><p>下面是一个php的测试demo。</p>
<pre class="brush:php;toolbar:false">header('Content-Type:text/html; charset=utf-8');
while(1){
    echo date('Y-m-d H:i:s');
    flush();
    sleep(1);
};

四、web 通信方式利弊分析

轮询,这种方式应该是最没技术含量的,操作起来最方便,不过是及时性不强,把定时器的间隔时间设置的短一些可以稍微得到缓和。

长轮询,算是比较不错的一个web通讯方式,不过每次断开连接,比较耗服务器资源,客户端到无所谓。

数据流,他和长轮询不同之处是接受数据的时间不一样,数据流是readystate为3的时候接受,低版本IE不太兼容,处理起来略麻烦,而且还要自己设计数据传输协议。不过他对资源的消耗比上面几种都可观。

websocket和EventSource,两个利器,不过,没几个浏览器支持,这是比较让人伤心~

ActionScript和Java Applet,两者都是需要在客户端安装插件的,一个是Flash插件,一个是Java插件,而且搞前端的人一般对这东西不太熟悉,如果没有封装比较好的库可以使用,那建议还是别用了。

更多编程相关知识,请访问:编程视频!!

以上是JavaScript中一些web通訊知識點總結(分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:博客园。如有侵權,請聯絡admin@php.cn刪除
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
1 個月前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器