WebSocket

WebSocket

1. WebSocket 理解

1.1 WebSocket出現(xiàn)的原因

我們已經(jīng)有了 HTTP 協(xié)議世落,為什么還需要另一個(gè)協(xié)議?

因?yàn)?HTTP 協(xié)議有一個(gè)缺陷:通信只能由客戶端發(fā)起。

這種單向請求的特點(diǎn)曾棕,注定了如果服務(wù)器有連續(xù)的狀態(tài)變化陋守,客戶端要獲知就非常麻煩橘原。因此我們只能使用"輪詢", 也就是每隔一段時(shí)候,就發(fā)出一個(gè)詢問郁妈,了解服務(wù)器有沒有新的信息浑玛。最典型的場景就是聊天室。

<body>
  <script>
    //http是單向的噩咪,要東西才會(huì)給
     setInterval(() => {
      $.ajax({   //每隔10s向后臺(tái)請求數(shù)據(jù)顾彰,這就是輪詢
        ...
      })
    }, 10000)
  </script>
</body>

然而輪詢的效率比較低, 非常 浪費(fèi)資源。輪詢的缺陷--后臺(tái)數(shù)據(jù)沒變胃碾,間隔響應(yīng)時(shí)間還會(huì)請求數(shù)據(jù)

因此為了更好地處理這種問題.WebSocket就 這樣被發(fā)明了

1.2 WebSocket 簡介

WebSocket 協(xié)議在2008年誕生涨享,2011年成為國際標(biāo)準(zhǔn)。所有瀏覽器都已經(jīng)支持了仆百。

它的最大特點(diǎn)就是厕隧,服務(wù)器可以主動(dòng)向客戶端推送信息,客戶端也可以主動(dòng)向服務(wù)器發(fā)送信息俄周,是真正的雙向平等對(duì)話吁讨,屬于服務(wù)器推送技術(shù)的一種。

特點(diǎn) :
  1. 建立在 TCP 協(xié)議之上峦朗,服務(wù)器端的實(shí)現(xiàn)比較容易建丧。

  2. 與 HTTP 協(xié)議有著良好的兼容性。默認(rèn)端口也是80和443波势,并且握手階段采用 HTTP 協(xié)議翎朱,因此握手時(shí)不容易屏蔽,能通過各種 HTTP 代理服務(wù)器

  3. 數(shù)據(jù)格式比較輕量艰亮,性能開銷小闭翩,通信高效。

  4. 可以發(fā)送文本迄埃,也可以發(fā)送二進(jìn)制數(shù)據(jù)疗韵。

  5. 沒有同源(跨域)限制,客戶端可以與任意服務(wù)器通信侄非。

  6. 協(xié)議標(biāo)識(shí)符是ws(如果加密蕉汪,則為wss),服務(wù)器網(wǎng)址就是 URL逞怨。

ws://example.com:80/some/path

2. 客戶端API

2.1 WebSocket 構(gòu)造函數(shù)

WebSocket 對(duì)象提供了用于創(chuàng)建和管理 WebSocket 連接者疤,以及可以通過該連接發(fā)送和接收數(shù)據(jù)的 API。

對(duì)于我們來時(shí)通過WebSocket構(gòu)造函數(shù)實(shí)例化WebSocket對(duì)象, 在實(shí)例化過程中連接服務(wù)器

語法;
var aWebSocket = new WebSocket(url);
參數(shù):
  1. url: 要連接的URL叠赦;這應(yīng)該是WebSocket服務(wù)器將響應(yīng)的URL

例子:

let ws = new WebSocket('ws://www.localhost:8080')在關(guān)閉
4. CLOSED: 值為3, 表示連
2.2 webSocket.readyState

實(shí)例的readyState 屬性返回實(shí)例對(duì)象的當(dāng)前狀態(tài), 共有四種狀態(tài)

  1. CONNECTING: 值為0, 表示正在連接
  2. OPEN: 值為1, 表示連接成功, 可以通信了
  3. CLOSING: 值為2, 表示連接正接已經(jīng)關(guān)閉, 或者 打開連接失敗
switch (ws.readyState) {
  case WebSocket.CONNECTING:
    break;
  case WebSocket.OPEN:
    break;
  case WebSocket.CLOSING:
    break;
  case WebSocket.CLOSED:
    break;
  default:
    break;
}
3 webSocket.onopen

實(shí)例對(duì)象的onopen 方法, 用于執(zhí)行連接成功后的回調(diào)函數(shù)

// socket 連接成功后觸發(fā)事件
ws.onopen = function(){
   // 像后端發(fā)送數(shù)據(jù) 
    ws.send("Hello Word")
}

如果需要指定多個(gè)回調(diào)函數(shù), 可以使用addEventListener事件綁定

ws.addEventListener('open', function (ev) {
   ws.send('Hello Server!');
});
ws.addEventListener('open', function (ev) {
   ws.send('你好');
});
2.4 webSocket.send()

實(shí)例對(duì)象的send()方法用于向服務(wù)器發(fā)送數(shù)據(jù)驹马。

發(fā)送文本數(shù)據(jù)

ws.send('hello word');

發(fā)送JSON數(shù)據(jù)

ws.send(JSON.stringify({name:'張三'}));
2.5 webSocket.onmessage

實(shí)例對(duì)象的onmessage屬性,用于指定收到服務(wù)器數(shù)據(jù)后的回調(diào)函數(shù)。

ws.onmessage = function(ev) {
  var data = ev.data;
  // 處理數(shù)據(jù)
};

ws.addEventListener("message", function(ev) {
  var data = ev.data;
  // 處理數(shù)據(jù)
});
2.6 webSocket.onclose

實(shí)例對(duì)象的onclose 屬性, 指定連接關(guān)閉后的回調(diào)函數(shù)

注意: socket連接失敗也會(huì)觸發(fā)onclose事件

ws.onclose = function(ev) {
  console.log('關(guān)閉socket連接', ev)
};

ws.addEventListener("close", function(event) {
  console.log('關(guān)閉socket連接', ev)
});
2.7 webSocket.onerror

實(shí)例對(duì)象的onerror屬性糯累,用于指定報(bào)錯(cuò)時(shí)的回調(diào)函數(shù)算利。

socket.onerror = function(ev) {
  // 處理錯(cuò)誤
};

socket.addEventListener("error", function(ev) {
  // 處理錯(cuò)誤
});

3. WebSocket 封裝

class JsSocket {

    /**
       *  構(gòu)造方法, 進(jìn)行初始化
       *  @param {String} url socket 連接地址
       * */
    constructor(url) {
        this.url = url;
        this.lockReconnect = false;
        this.reconnectCount = 0
    }

    /**
       * 開始連接
       * @params { Function } callback  
       * */
    connect(callback) {
        this.callback = callback;
        this.disconnect()

        try {
            console.log("JsSocket開始連接...", this.url)
            this.ws = new WebSocket(this.url)

            this.ws.onopen = function(ev) {
                console.log("JsSocket onpen...", ev)
                this.reconnectTimes = 0
            }

            this.ws.onmessage = function(ev) {
                console.log("JsSocket onmessage...", ev)
                let data = ev.data;
                if (!data) {
                    data = JSON.parse(data)
                }


                callback(data)
            }

            this.ws.onclose = (ev) => {
                console.log("JsSocket onclose...", ev)
                this.reconnect()
            }

            this.ws.onerror = (ev) => {
                console.log("JsSocket onerror...", ev)
                this.reconnect()
            }
        } catch (error) {
            console.log("JsSocket", error)
        }
    }


    /**
       * 斷開連接
       * */
    disconnect() {
        if (this.ws) {
            this.ws.onclose = null;
            this.ws.close()
            this.ws = null
        }
    }


    /**
       * 發(fā)送消息
       * @params { Object } data 消息內(nèi)容
       * */
    send(data) {
        if (this.ws) {
            this.ws.send(data)
        }
    }


    /**
       * 重新連接
       * */
    reconnect() {
        if (this.lockReconnect || this.reconnectCount > 5) {
            console.log('JsSocket 重連鎖定 或者 超過重連次數(shù)')
            return;
        }
        this.lockReconnect = true;
        setTimeout(() => {
            this.reconnectCount++;
            console.log('JsSocket 重連...')
            this.connect(this.callback)
            this.lockReconnect = false
        }, 3000)
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市泳姐,隨后出現(xiàn)的幾起案子效拭,更是在濱河造成了極大的恐慌,老刑警劉巖胖秒,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缎患,死亡現(xiàn)場離奇詭異,居然都是意外死亡阎肝,警方通過查閱死者的電腦和手機(jī)挤渔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盗痒,“玉大人蚂蕴,你說我怎么就攤上這事「┑耍” “怎么了骡楼?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長稽鞭。 經(jīng)常有香客問我鸟整,道長,這世上最難降的妖魔是什么朦蕴? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任篮条,我火速辦了婚禮,結(jié)果婚禮上吩抓,老公的妹妹穿的比我還像新娘涉茧。我一直安慰自己,他們只是感情好疹娶,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布伴栓。 她就那樣靜靜地躺著,像睡著了一般雨饺。 火紅的嫁衣襯著肌膚如雪钳垮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天额港,我揣著相機(jī)與錄音饺窿,去河邊找鬼。 笑死移斩,一個(gè)胖子當(dāng)著我的面吹牛肚医,可吹牛的內(nèi)容都是我干的绢馍。 我是一名探鬼主播,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼肠套,長吁一口氣:“原來是場噩夢啊……” “哼痕貌!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起糠排,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎超升,沒想到半個(gè)月后入宦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡室琢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年乾闰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盈滴。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涯肩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出巢钓,到底是詐尸還是另有隱情病苗,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布症汹,位于F島的核電站硫朦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏背镇。R本人自食惡果不足惜咬展,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瞒斩。 院中可真熱鬧破婆,春花似錦、人聲如沸胸囱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旺矾。三九已至蔑鹦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間箕宙,已是汗流浹背嚎朽。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柬帕,地道東北人哟忍。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓狡门,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锅很。 傳聞我的和親對(duì)象是個(gè)殘疾皇子其馏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 本文介紹 WebSocket 協(xié)議的使用方法。 一爆安、為什么需要 WebSocket叛复? 初次接觸 WebSocket...
    安易學(xué)車閱讀 376評(píng)論 0 0
  • WebSocket是一種網(wǎng)絡(luò)通信協(xié)議。 為什么需要 WebSocket扔仓? 因?yàn)镠TTP 協(xié)議有一個(gè)缺陷:通信只能由...
    葶寳寳閱讀 3,224評(píng)論 0 11
  • Web Sockets ——新瀏覽器 API Web Sockets 的目標(biāo)是在一個(gè)單獨(dú)的持久連接上提供全雙工褐奥、雙...
    逆風(fēng)飄游的魚閱讀 873評(píng)論 0 0
  • 一:背景介紹 近年來,隨著HTML5的誕生翘簇,WebSocket協(xié)議被提出撬码,它實(shí)現(xiàn)了瀏覽器與服務(wù)器的全雙工通信,擴(kuò)展...
    大大大大大西瓜G閱讀 709評(píng)論 0 3
  • 前言 之前一個(gè)項(xiàng)目中九風(fēng)開發(fā)app的用戶的消息部分版保,由于項(xiàng)目比較緊呜笑,而且之前沒有接觸過WebSocket開發(fā),所以...
    九風(fēng)萍舟閱讀 163,639評(píng)論 24 98