這篇文章將為大家詳細講解有關(guān)websocket有什么用,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

Websocket是一個持久化的網(wǎng)絡(luò)通信協(xié)議,可以在單個 TCP 連接上進行全雙工通訊,沒有了Request和Response的概念,兩者地位完全平等,連接一旦建立,客戶端和服務(wù)端之間實時可以進行雙向數(shù)據(jù)傳輸
HTTP
HTTP是非持久的協(xié)議,客戶端想知道服務(wù)端的處理進度只能通過不停地使用Ajax進行輪詢或者采用long poll 的方式來,但是前者對服務(wù)器壓力大,后者則會因為一直等待Response造成阻塞
雖然http1.1默認開啟了keep-alive長連接保持了這個TCP通道使得在一個HTTP連接中,可以發(fā)送多個Request,接收多個Response,但是一個request只能有一個response。而且這個response也是被動的,不能主動發(fā)起。
websocket雖然是獨立于HTTP的一種協(xié)議,但是websocket必須依賴 HTTP 協(xié)議進行一次握手(在握手階段是一樣的),握手成功后,數(shù)據(jù)就直接從 TCP通道傳輸,與 HTTP 無關(guān)了,可以用一張圖理解兩者有交集,但是并不是全部。
socket
socket也被稱為套接字,與HTTP和WebSocket不一樣,socket不是協(xié)議,它是在程序?qū)用嫔蠈鬏攲訁f(xié)議(可以主要理解為TCP/IP)的接口封裝。可以理解為一個能夠提供端對端的通信的調(diào)用接口(API)
對于程序員而言,其需要在 A 端創(chuàng)建一個 socket 實例,并為這個實例提供其所要連接的 B 端的 IP 地址和端口號,而在 B 端創(chuàng)建另一個 socket 實例,并且綁定本地端口號來進行監(jiān)聽。當(dāng) A 和 B 建立連接后,雙方就建立了一個端對端的 TCP 連接,從而可以進行雙向通信。WebSocekt借鑒了 socket 的思想,為 client 和 server 之間提供了類似的雙向通信機制
WebSocket可以做彈幕、消息訂閱、多玩家游戲、協(xié)同編輯、股票基金實時報價、視頻會議、在線教育、聊天室等應(yīng)用實時監(jiān)聽服務(wù)端變化
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
下面是與傳統(tǒng) HTTP 報文不同的地方:
Upgrade: websocket Connection: Upgrade
表示發(fā)起的是 WebSocket 協(xié)議
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13
Sec-WebSocket-Key 是由瀏覽器隨機生成的,驗證是否可以進行Websocket通信,防止惡意或者無意的連接。
Sec_WebSocket-Protocol 是用戶自定義的字符串,用來標(biāo)識服務(wù)所需要的協(xié)議
Sec-WebSocket-Version 表示支持的 WebSocket 版本。
服務(wù)器響應(yīng):
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat
101 響應(yīng)碼 表示要轉(zhuǎn)換協(xié)議。
Connection: Upgrade 表示升級新協(xié)議請求。
Upgrade: websocket 表示升級為 WebSocket 協(xié)議。
Sec-WebSocket-Accept 是經(jīng)過服務(wù)器確認,并且加密過后的 Sec-WebSocket-Key。用來證明客戶端和服務(wù)器之間能進行通信了。
Sec-WebSocket-Protocol 表示最終使用的協(xié)議。
至此,客戶端和服務(wù)器握手成功建立了Websocket連接,HTTP已經(jīng)完成它所有工作了,接下來就是完全按照Websocket協(xié)議進行通信了。
可能會有一些未知情況導(dǎo)致SOCKET斷開,而客戶端和服務(wù)端卻不知道,需要客戶端定時發(fā)送一個心跳 Ping 讓服務(wù)端知道自己在線,而服務(wù)端也要回復(fù)一個心跳 Pong告訴客戶端自己可用,否則視為斷開
WebSocket 對象中的readyState屬性有四種狀態(tài):
0: 表示正在連接
1: 表示連接成功,可以通信了
2: 表示連接正在關(guān)閉
3: 表示連接已經(jīng)關(guān)閉,或者打開連接失敗
WebSocket的服務(wù)端部分,本文會以Node.js搭建
安裝express和負責(zé)處理WebSocket協(xié)議的ws:
npm install express ws
安裝成功后的package.json:
接著在根目錄創(chuàng)建server.js文件:
//引入express 和 ws
const express = require('express');
const SocketServer = require('ws').Server;
//指定開啟的端口號
const PORT = 3000;
// 創(chuàng)建express,綁定監(jiān)聽3000端口,且設(shè)定開啟后在consol中提示
const server = express().listen(PORT, () => console.log(`Listening on ${PORT}`));
// 將express交給SocketServer開啟WebSocket的服務(wù)
const wss = new SocketServer({ server });
//當(dāng) WebSocket 從外部連接時執(zhí)行
wss.on('connection', (ws) => {
//連接時執(zhí)行此 console 提示
console.log('Client connected');
// 對message設(shè)置監(jiān)聽,接收從客戶端發(fā)送的消息
ws.on('message', (data) => {
//data為客戶端發(fā)送的消息,將消息原封不動返回回去
ws.send(data);
});
// 當(dāng)WebSocket的連接關(guān)閉時執(zhí)行
ws.on('close', () => {
console.log('Close connected');
});
});執(zhí)行node server.js啟動服務(wù),端口打開后會執(zhí)行監(jiān)聽時間打印提示,說明服務(wù)啟動成功
在開啟WebSocket后,服務(wù)端會在message中監(jiān)聽,接收參數(shù)data捕獲客戶端發(fā)送的消息,然后使用send發(fā)送消息
分別在根目錄創(chuàng)建index.html和index.js文件
index.html
<html> <body> <script src="./index.js"></script> </body> </html>
index.js
// 使用WebSocket的地址向服務(wù)端開啟連接
let ws = new WebSocket('ws://localhost:3000');
// 開啟后的動作,指定在連接后執(zhí)行的事件
ws.onopen = () => {
console.log('open connection');
};
// 接收服務(wù)端發(fā)送的消息
ws.onmessage = (event) => {
console.log(event);
};
// 指定在關(guān)閉后執(zhí)行的事件
ws.onclose = () => {
console.log('close connection');
};上面的url就是本機node開啟的服務(wù)地址,分別指定連接(onopen),關(guān)閉(onclose)和消息接收(onmessage)的執(zhí)行事件,訪問html,打印ws信息
打印了open connection說明連接成功,客戶端會使用onmessage處理接收
其中event參數(shù)包含這次溝通的詳細信息,從服務(wù)端回傳的消息會在event的data屬性中。
手動在控制臺調(diào)用send發(fā)送消息,打印event回傳信息:
上面是從客戶端發(fā)送消息,服務(wù)端回傳。我們也可以通過setInterval讓服務(wù)端在固定時間發(fā)送消息給客戶端:
server.js修改如下:
//當(dāng)WebSocket從外部連接時執(zhí)行
wss.on('connection', (ws) => {
//連接時執(zhí)行此 console 提示
console.log('Client connected');
+ //固定發(fā)送新消息給客戶端
+ const sendNowTime = setInterval(() => {
+ ws.send(String(new Date()));
+ }, 1000);
- //對message設(shè)置監(jiān)聽,接收從客戶端發(fā)送的消息
- ws.on('message', (data) => {
- //data為客戶端發(fā)送的消息,將消息原封不動返回回去
- ws.send(data);
- });
//當(dāng) WebSocket的連接關(guān)閉時執(zhí)行
ws.on('close', () => {
console.log('Close connected');
});
});客戶端連接后就會定時接收,直至我們關(guān)閉websocket服務(wù)
如果多個客戶端連接按照上面的方式只會返回各自發(fā)送的消息,先注釋服務(wù)端定時發(fā)送,開啟兩個窗口模擬:
如果我們要讓客戶端間消息共享,也同時接收到服務(wù)端回傳的消息呢?
我們可以使用clients找出當(dāng)前所有連接中的客戶端 ,并通過回傳消息發(fā)送到每一個客戶端 中:
修改server.js如下:
...
//當(dāng)WebSocket從外部連接時執(zhí)行
wss.on('connection', (ws) => {
//連接時執(zhí)行此 console 提示
console.log('Client connected');
- //固定發(fā)送新消息給客戶端
- const sendNowTime = setInterval(() => {
- ws.send(String(new Date()));
- }, 1000);
+ //對message設(shè)置監(jiān)聽,接收從客戶端發(fā)送的消息
+ ws.on('message', (data) => {
+ //取得所有連接中的 客戶端
+ let clients = wss.clients;
+ //循環(huán),發(fā)送消息至每個客戶端
+ clients.forEach((client) => {
+ client.send(data);
+ });
+ });
//當(dāng)WebSocket的連接關(guān)閉時執(zhí)行
ws.on('close', () => {
console.log('Close connected');
});
});關(guān)于“websocket有什么用”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
網(wǎng)站欄目:websocket有什么用-創(chuàng)新互聯(lián)
文章位置:http://www.chinadenli.net/article32/pcdpc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、虛擬主機、品牌網(wǎng)站設(shè)計、小程序開發(fā)、網(wǎng)站營銷、響應(yīng)式網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容