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