站長資訊網
        最全最豐富的資訊網站

        十分鐘快速了解websocket!!

        十分鐘快速了解websocket!!

        什么是WebSocket

        定義

        Websocket是一個持久化的網絡通信協議,可以在單個 TCP 連接上進行全雙工通訊,沒有了RequestResponse的概念,兩者地位完全平等,連接一旦建立,客戶端和服務端之間實時可以進行雙向數據傳輸

        關聯和區別

        • HTTP
        1. HTTP是非持久的協議,客戶端想知道服務端的處理進度只能通過不停地使用 Ajax進行輪詢或者采用 long poll 的方式來,但是前者對服務器壓力大,后者則會因為一直等待Response造成阻塞 十分鐘快速了解websocket!!
        2. 雖然http1.1默認開啟了keep-alive長連接保持了這個TCP通道使得在一個HTTP連接中,可以發送多個Request,接收多個Response,但是一個request只能有一個response。而且這個response也是被動的,不能主動發起。
        3. websocket雖然是獨立于HTTP的一種協議,但是websocket必須依賴 HTTP 協議進行一次握手(在握手階段是一樣的),握手成功后,數據就直接從 TCP通道傳輸,與 HTTP 無關了,可以用一張圖理解兩者有交集,但是并不是全部。 十分鐘快速了解websocket!!
        • socket
        1. socket也被稱為套接字,與HTTP和WebSocket不一樣,socket不是協議,它是在程序層面上對傳輸層協議(可以主要理解為TCP/IP)的接口封裝。可以理解為一個能夠提供端對端的通信的調用接口(API)
        2. 對于程序員而言,其需要在 A 端創建一個 socket 實例,并為這個實例提供其所要連接的 B 端的 IP 地址和端口號,而在 B 端創建另一個 socket 實例,并且綁定本地端口號來進行監聽。當 A 和 B 建立連接后,雙方就建立了一個端對端的 TCP 連接,從而可以進行雙向通信。WebSocekt借鑒了 socket 的思想,為 client 和 server 之間提供了類似的雙向通信機制

        應用場景

        WebSocket可以做彈幕、消息訂閱、多玩家游戲、協同編輯、股票基金實時報價、視頻會議、在線教育、聊天室等應用實時監聽服務端變化

        Websocket握手

        • Websocket握手請求報文:
        GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 Origin: http://example.com

        下面是與傳統 HTTP 報文不同的地方:

        Upgrade: websocket Connection: Upgrade

        表示發起的是 WebSocket 協議

        Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13

        Sec-WebSocket-Key 是由瀏覽器隨機生成的,驗證是否可以進行Websocket通信,防止惡意或者無意的連接。

        Sec_WebSocket-Protocol 是用戶自定義的字符串,用來標識服務所需要的協議

        Sec-WebSocket-Version 表示支持的 WebSocket 版本。

        • 服務器響應:
        HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat

        101 響應碼 表示要轉換協議。

        Connection: Upgrade 表示升級新協議請求。

        Upgrade: websocket 表示升級為 WebSocket 協議。

        Sec-WebSocket-Accept 是經過服務器確認,并且加密過后的 Sec-WebSocket-Key。用來證明客戶端和服務器之間能進行通信了。

        Sec-WebSocket-Protocol 表示最終使用的協議。

        至此,客戶端和服務器握手成功建立了Websocket連接,HTTP已經完成它所有工作了,接下來就是完全按照Websocket協議進行通信了。

        關于Websocket

        WebSocket心跳

        可能會有一些未知情況導致SOCKET斷開,而客戶端和服務端卻不知道,需要客戶端定時發送一個心跳 Ping 讓服務端知道自己在線,而服務端也要回復一個心跳 Pong告訴客戶端自己可用,否則視為斷開

        WebSocket狀態

        WebSocket 對象中的readyState屬性有四種狀態:

        • 0: 表示正在連接
        • 1: 表示連接成功,可以通信了
        • 2: 表示連接正在關閉
        • 3: 表示連接已經關閉,或者打開連接失敗

        WebSocket實踐

        服務端接收發送消息

        WebSocket的服務端部分,本文會以Node.js搭建

        安裝express和負責處理WebSocket協議的ws

        npm install express ws

        安裝成功后的package.json:

        接著在根目錄創建server.js文件:

        //引入express 和 ws const express = require('express'); const SocketServer = require('ws').Server; //指定開啟的端口號 const PORT = 3000; // 創建express,綁定監聽3000端口,且設定開啟后在consol中提示 const server = express().listen(PORT, () => console.log(`Listening on ${PORT}`)); // 將express交給SocketServer開啟WebSocket的服務 const wss = new SocketServer({ server }); //當 WebSocket 從外部連接時執行 wss.on('connection', (ws) => {   //連接時執行此 console 提示   console.log('Client connected');   // 對message設置監聽,接收從客戶端發送的消息   ws.on('message', (data) => {     //data為客戶端發送的消息,將消息原封不動返回回去     ws.send(data);   });   // 當WebSocket的連接關閉時執行   ws.on('close', () => {     console.log('Close connected');   }); });

        執行node server.js啟動服務,端口打開后會執行監聽時間打印提示,說明服務啟動成功

        在開啟WebSocket后,服務端會在message中監聽,接收參數data捕獲客戶端發送的消息,然后使用send發送消息

        客戶端接收發送消息

        分別在根目錄創建index.html和index.js文件

        • index.html
        <html>   <body>     <script src="./index.js"></script>   </body> </html>
        • index.js
        // 使用WebSocket的地址向服務端開啟連接 let ws = new WebSocket('ws://localhost:3000'); // 開啟后的動作,指定在連接后執行的事件 ws.onopen = () => {   console.log('open connection'); }; // 接收服務端發送的消息 ws.onmessage = (event) => {   console.log(event); }; // 指定在關閉后執行的事件 ws.onclose = () => {   console.log('close connection'); };

        上面的url就是本機node開啟的服務地址,分別指定連接(onopen),關閉(onclose)和消息接收(onmessage)的執行事件,訪問html,打印ws信息

        打印了open connection說明連接成功,客戶端會使用onmessage處理接收

        其中event參數包含這次溝通的詳細信息,從服務端回傳的消息會在event的data屬性中。

        手動在控制臺調用send發送消息,打印event回傳信息:

        服務端定時發送

        上面是從客戶端發送消息,服務端回傳。我們也可以通過setInterval讓服務端在固定時間發送消息給客戶端:

        server.js修改如下:

        //當WebSocket從外部連接時執行 wss.on('connection', (ws) => {   //連接時執行此 console 提示   console.log('Client connected'); +  //固定發送最新消息給客戶端 +  const sendNowTime = setInterval(() => { +    ws.send(String(new Date())); +  }, 1000); -  //對message設置監聽,接收從客戶端發送的消息 -  ws.on('message', (data) => { -    //data為客戶端發送的消息,將消息原封不動返回回去 -    ws.send(data); -  });   //當 WebSocket的連接關閉時執行   ws.on('close', () => {     console.log('Close connected');   }); });

        客戶端連接后就會定時接收,直至我們關閉websocket服務

        多人聊天

        如果多個客戶端連接按照上面的方式只會返回各自發送的消息,先注釋服務端定時發送,開啟兩個窗口模擬:

        如果我們要讓客戶端間消息共享,也同時接收到服務端回傳的消息呢?

        我們可以使用clients找出當前所有連接中的客戶端 ,并通過回傳消息發送到每一個客戶端 中:

        修改server.js如下:

        ... //當WebSocket從外部連接時執行 wss.on('connection', (ws) => {   //連接時執行此 console 提示   console.log('Client connected'); -  //固定發送最新消息給客戶端 -  const sendNowTime = setInterval(() => { -    ws.send(String(new Date())); - }, 1000); +  //對message設置監聽,接收從客戶端發送的消息 +   ws.on('message', (data) => { +    //取得所有連接中的 客戶端 +    let clients = wss.clients; +    //循環,發送消息至每個客戶端 +    clients.forEach((client) => { +      client.send(data); +    }); +   });   //當WebSocket的連接關閉時執行   ws.on('close', () => {     console.log('Close connected');   }); });

        這樣一來,不論在哪個客戶端發送消息,服務端都能將消息回傳到每個客戶端 : 十分鐘快速了解websocket!! 可以觀察下連接信息: 十分鐘快速了解websocket!!

        總結

        紙上得來終覺淺,絕知此事要躬行,希望大家可以把理論配合上面的實例進行消化,搭好服務端也可以直接使用測試工具好好玩耍一波

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 精品黑人一区二区三区| 99在线精品视频观看免费| 日本VA欧美VA欧美VA精品| 亚洲色图国产精品| 国语自产少妇精品视频蜜桃| 久久精品人妻一区二区三区| 在线人成精品免费视频| 2021国产成人精品国产| 亚洲AV无码成人精品区在线观看 | 九九精品在线观看| 久久精品99久久香蕉国产色戒 | 国产一级精品高清一级毛片 | 久久精品国产69国产精品亚洲| 久久精品一本到99热免费| 四虎永久在线精品免费一区二区| 国产啪亚洲国产精品无码 | 久久精品中文闷骚内射| 亚洲精品狼友在线播放| 完整观看高清秒播国内外精品资源| 国产精品内射久久久久欢欢| 9久热这里只有精品| 99久久国产综合精品成人影院 | 亚洲日韩精品无码专区网站| 欧美精品色婷婷五月综合| 九色精品视频在线观看| 国产亚洲精品拍拍拍拍拍| 国产亚洲午夜高清国产拍精品| 国产精品久久久天天影视香蕉 | 国产精品日本一区二区不卡视频| 日韩人妻无码精品久久免费一| 无码国模国产在线无码精品国产自在久国产 | 国产欧美日韩综合精品一区二区三区 | www.亚洲精品| 久久99国产精品久久| 精品午夜久久福利大片| 久久精品视频网| 91精品国产品国语在线不卡| 国产99精品一区二区三区免费| 国产精品极品| 免费精品视频在线| 亚洲日韩国产AV无码无码精品 |