摘要:什么是是一種在單個(gè)連接上進(jìn)行全雙工通信的協(xié)議。短輪詢配段代碼,靜態(tài)服務(wù)中間件用來(lái)返回靜態(tài)文件當(dāng)前價(jià)格是元獲取最新價(jià)格接口客戶端不停的發(fā)送請(qǐng)求,去服務(wù)端獲取最新價(jià)格。它通過(guò)連接到一個(gè)服務(wù)器,以格式接收事件不關(guān)閉連接。
什么是WebSocket?
WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議。這里我們發(fā)現(xiàn)了一個(gè)有趣的詞:”全雙工”,那我們就來(lái)簡(jiǎn)單了解下通信方式有哪些!
單工通信雙方中,一方固定為發(fā)送端,一方則固定為接收端。信息只能沿一個(gè)方向傳輸。
例如計(jì)算機(jī)與打印機(jī)之間的通信是單工模式
說(shuō)的簡(jiǎn)單些就是:我打你你只能忍著!
允許數(shù)據(jù)在兩個(gè)方向上傳輸,但是同一時(shí)間數(shù)據(jù)只能在一個(gè)方向上傳輸,其實(shí)際上是切換的單工。
例如HTTP協(xié)議:客戶端向服務(wù)器發(fā)送請(qǐng)求(單向的),然后服務(wù)器響應(yīng)請(qǐng)求(單向的)
說(shuō)的簡(jiǎn)單些就是:我打你,你忍完后可以打我,我忍著…
允許數(shù)據(jù)在兩個(gè)方向上同時(shí)傳輸。
例如手機(jī)通話,WebSocket就是這個(gè)樣子!
說(shuō)的簡(jiǎn)單些就是:兩個(gè)人同時(shí)可以互相打?qū)Ψ?br>
說(shuō)了這么多其實(shí)目的就是讓大家知道,WebSocket是支持雙向通信的!雙向通信的優(yōu)點(diǎn)
為什么要支持雙向通信?單向通信有什么問(wèn)題?還是從HTTP說(shuō)起,我們知道HTTP協(xié)議是半雙工的,而且服務(wù)器不能主動(dòng)推送消息給瀏覽器!這個(gè)就是他的缺陷。假若我希望實(shí)現(xiàn)一個(gè)股票交易系統(tǒng),可能股價(jià)每秒鐘都有變化,但是價(jià)格變化了如何通知我們的客戶端?
咱們來(lái)看看以前是怎么實(shí)現(xiàn)的!
輪詢什么叫輪詢?就是不停的輪番詢問(wèn)!說(shuō)的直白些就是客戶端定期發(fā)送請(qǐng)求給服務(wù)端。
配段代碼,Talk is cheap,show me your code.
const express = require("express"); const app = express(); // express 靜態(tài)服務(wù)中間件用來(lái)返回靜態(tài)文件 app.use(express.static(__dirname)); // 當(dāng)前價(jià)格是100元 let currentPrice = 100; // 獲取最新價(jià)格接口 app.get("/getPrice", (req, res, next) => { res.send("¥"+currentPrice * Math.random()); }); app.listen(3000);
客戶端不停的發(fā)送請(qǐng)求,去服務(wù)端獲取最新價(jià)格。
當(dāng)前交易價(jià)格:
很快我們就看出了這樣編寫代碼的缺陷!如果數(shù)據(jù)變化的不快呢,那就會(huì)發(fā)送很多無(wú)意義的請(qǐng)求。每次發(fā)送請(qǐng)求都會(huì)有HTTP的Header會(huì)消耗大量流量,同時(shí)也會(huì)消耗CPU的利用率!長(zhǎng)輪詢
長(zhǎng)輪詢是對(duì)短輪詢的改進(jìn)版,就是當(dāng)?shù)谝粋€(gè)請(qǐng)求回來(lái)時(shí)再發(fā)送下一個(gè)請(qǐng)求!
(function poll(){ fetch("/getPrice"). then(res=>res.text()). then(data=>{price.innerHTML = data;poll()}) })()
問(wèn)題依舊是顯而易見的!如果服務(wù)端數(shù)據(jù)變化很快,那么請(qǐng)求數(shù)目會(huì)更多;如果變化很慢,可能ajax會(huì)出現(xiàn)超時(shí)的問(wèn)題。Iframe方式
我們并不希望每次都創(chuàng)建一個(gè)新的請(qǐng)求,此時(shí)就可以使用Iframe來(lái)實(shí)現(xiàn)長(zhǎng)連接
app.get("/getPrice", (req, res, next) => { setInterval(()=>{ // 不能使用end 否則會(huì)中斷請(qǐng)求,我們要實(shí)現(xiàn)的是長(zhǎng)連接 res.write(` `); },1000); });
當(dāng)前交易價(jià)格:
現(xiàn)在確實(shí)可以利用Iframe實(shí)現(xiàn)了長(zhǎng)連接通信,但是頁(yè)面的狀態(tài)一直是加載態(tài)!EventSource流
EventSource 接口用于接收服務(wù)器發(fā)送的事件。它通過(guò)HTTP連接到一個(gè)服務(wù)器,以text/event-stream 格式接收事件, 不關(guān)閉連接。
當(dāng)前交易價(jià)格:
app.get("/getPrice", (req, res, next) => { res.header("Content-Type","text/event-stream",); timer = setInterval(()=>{ res.write( // 發(fā)送message事件 表示當(dāng)前的event-stream通信結(jié)束 `event:message id:${id++} data:${currentPrice*Math.random()} ` ); },1000); res.on("close",()=>{ clearInterval(timer); }); });
當(dāng)然這種方式依舊是單向的,主要是服務(wù)端向客戶端推送數(shù)據(jù)。并且兼容性也不是很美麗~WebSocket
終于等到你! 雙向通信的WebSocket讓你欲罷不能!
WebSocket讓客戶端和服務(wù)器保有一個(gè)持久的連接,兩邊可以在任意時(shí)間開始發(fā)送數(shù)據(jù)!它是基于TCP協(xié)議的:
先來(lái)聊聊WebSocket的優(yōu)勢(shì)!
http協(xié)議不支持雙向通信 -> 我支持雙向通信
http協(xié)議數(shù)據(jù)包頭部較大 -> 我的header很小!我最少只需兩個(gè)字節(jié)
http不支持跨域 -> 我支持跨域,哈哈!
ws模塊ws: a Node.js WebSocket library,ok就是在node中可以使用的WebSocket庫(kù)!
安裝ws模塊
yarn add ws
服務(wù)端開啟WebSocket服務(wù)
const WebSocketServer = require("ws").Server; const ws = new WebSocketServer({port:8888}); ws.on("connection",(socket)=>{ // socket鏈接我的那個(gè)人 console.log("服務(wù)端:有人鏈接我!"); socket.on("message",(data)=>{ console.log(data); // 收到客戶端發(fā)來(lái)的消息 socket.send("我是服務(wù)端"); // 給客戶端發(fā)消息 }); });
客戶端鏈接8888端口的ws服務(wù)!
const socket = new WebSocket("ws://localhost:8888"); socket.onopen = function(){ // 鏈接成功后,發(fā)送消息 console.log("客戶端:鏈接成功"); socket.send("我是客戶端"); } socket.onmessage = function(e){ // 監(jiān)聽客戶端發(fā)來(lái)的信息 console.log(e.data); }
客戶端和服務(wù)端可以開心的互相通信啦!socket.io
socket.io是一個(gè)WebSocket庫(kù),包括了客戶端的js和服務(wù)器端的nodejs,剛才是不是高興的太早了而忘記了兼容性問(wèn)題?沒錯(cuò)socket.io就是幫你解決自動(dòng)根據(jù)瀏覽器從WebSocket、AJAX長(zhǎng)輪詢、Iframe流等等各種方式中選擇最佳的方式來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)實(shí)時(shí)應(yīng)用!
安裝socket.io模塊
yarn add socket.io
通過(guò)socket.io建立鏈接
const express = require("express"); const app = express(); app.use(express.static(__dirname)) const server = require("http").createServer(app); // app本身就是監(jiān)聽函數(shù) // socket 需要借助http服務(wù) const io = require("socket.io")(server); // 劃分路徑 / io.of("/").on("connection",function(socket){ console.log("鏈接成功") socket.on("message",function(msg){ console.log(msg); socket.send("我是服務(wù)端"); }); }); // 監(jiān)聽3000 端口 server.listen(3000);
// 默認(rèn)會(huì)像瀏覽器中注入socket.io.js腳本
我們有了socket.io實(shí)現(xiàn)雙向通信是不是很簡(jiǎn)單!
覺得本文對(duì)你有幫助嗎?請(qǐng)分享給更多人
關(guān)注「前端優(yōu)選」加星標(biāo),提升前端技能
關(guān)注公眾號(hào),獲得更多前端高級(jí)技能
加我微信:webyouxuan
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/116361.html
摘要:什么是是一種在單個(gè)連接上進(jìn)行全雙工通信的協(xié)議。短輪詢配段代碼,靜態(tài)服務(wù)中間件用來(lái)返回靜態(tài)文件當(dāng)前價(jià)格是元獲取最新價(jià)格接口客戶端不停的發(fā)送請(qǐng)求,去服務(wù)端獲取最新價(jià)格。它通過(guò)連接到一個(gè)服務(wù)器,以格式接收事件不關(guān)閉連接。 什么是WebSocket? WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議。這里我們發(fā)現(xiàn)了一個(gè)有趣的詞:全雙工,那我們就來(lái)簡(jiǎn)單了解下通信方式有哪些! 單工 ...
摘要:早期的輪詢是通過(guò)不斷自動(dòng)刷新頁(yè)面而實(shí)現(xiàn)的。長(zhǎng)輪詢的另一個(gè)問(wèn)題是缺乏標(biāo)準(zhǔn)實(shí)現(xiàn)。服務(wù)器端接到這個(gè)請(qǐng)求后作出回應(yīng)并不斷更新連接狀態(tài)以保證客戶端和服務(wù)器端的連接不過(guò)期。協(xié)議解析協(xié)議包含兩部分一部分是握手,一部分是數(shù)據(jù)傳輸。 Websocket是什么? Websocket是一個(gè)因?yàn)閼?yīng)用場(chǎng)景越來(lái)越復(fù)雜而提出的,針對(duì)瀏覽器和web服務(wù)器之間雙向持續(xù)通信而設(shè)計(jì),而且優(yōu)雅地兼容HTTP的協(xié)議(我猜想:同...
摘要:我們只需引入如下依賴即可注入首先注入一個(gè)該會(huì)自動(dòng)注冊(cè)使用注解申明的。 一、背景 ??我們都知道 http 協(xié)議只能瀏覽器單方面向服務(wù)器發(fā)起請(qǐng)求獲得響應(yīng),服務(wù)器不能主動(dòng)向?yàn)g覽器推送消息。想要實(shí)現(xiàn)瀏覽器的主動(dòng)推送有兩種主流實(shí)現(xiàn)方式: 輪詢:缺點(diǎn)很多,但是實(shí)現(xiàn)簡(jiǎn)單 websocket:在瀏覽器和服務(wù)器之間建立 tcp 連接,實(shí)現(xiàn)全雙工通信 ??springboot 使用 websocket 有...
摘要:本文是面向前端小白的,大手子可以跳過(guò),寫的不好之處多多分鐘搞定常用基礎(chǔ)知識(shí)前端掘金基礎(chǔ)智商劃重點(diǎn)在實(shí)際開發(fā)中,已經(jīng)非常普及了。 JavaScript字符串所有API全解密 - 掘金關(guān)于 我的博客:louis blog SF專欄:路易斯前端深度課 原文鏈接:JavaScript字符串所有API全解密 本文近 6k 字,讀完需 10 分鐘。 字符串作為基本的信息交流的橋梁,幾乎被所有的編程...
摘要:通信服務(wù)提供接口是如何與區(qū)塊鏈交互的關(guān)鍵。這通常通過(guò)將請(qǐng)求提交給基于或套接字的服務(wù)器來(lái)完成。初始化時(shí)會(huì)發(fā)生自動(dòng)檢測(cè)有時(shí),無(wú)法自動(dòng)檢測(cè)節(jié)點(diǎn)的位置。使用自動(dòng)檢測(cè)的示例一些節(jié)點(diǎn)提供超出標(biāo)準(zhǔn)的。是套接字的文件系統(tǒng)路徑。 通信服務(wù)提供接口是web3如何與區(qū)塊鏈交互的關(guān)鍵。接口接受JSON-RPC請(qǐng)求并返回響應(yīng)。這通常通過(guò)將請(qǐng)求提交給基于HTTP或IPC套接字的服務(wù)器來(lái)完成。 如果你已經(jīng)愉快地連接...
閱讀 2972·2021-10-27 14:16
閱讀 694·2021-10-13 09:39
閱讀 3669·2021-09-29 09:46
閱讀 2087·2019-08-30 15:54
閱讀 2596·2019-08-30 15:52
閱讀 2994·2019-08-30 15:44
閱讀 1103·2019-08-30 15:44
閱讀 496·2019-08-30 10:51