websocket是什么
websocket相比于Http而言是一個(gè)雙向通信的協(xié)議赌厅,并且一直保持活動(dòng)狀態(tài)穷绵,直到客戶端或者服務(wù)端斷開。
主要用于監(jiān)聽特愿、消息仲墨、通知等需要實(shí)時(shí)反饋消息的場(chǎng)景勾缭。
如:聊天場(chǎng)景、下載進(jìn)度目养、發(fā)布系統(tǒng)日志反饋
等俩由。
當(dāng)然也可以通過Http輪詢來(lái)實(shí)現(xiàn)以上場(chǎng)景,不過websocket相較http更輕更快癌蚁。
采用http輪詢需要反復(fù)的鏈接幻梯、斷開連接更加消耗瀏覽器資源。
- HTTP 是無(wú)狀態(tài)的努释,也就是說碘梢,它將每個(gè)請(qǐng)求當(dāng)成唯一和獨(dú)立的。無(wú)狀態(tài)協(xié)議具有一些優(yōu)勢(shì)伐蒂,例如煞躬,服務(wù)器不需要保存有關(guān)會(huì)話的信息,從而不需要存儲(chǔ)數(shù)據(jù)饿自。但是汰翠,這也意味著在每次 HTTP 請(qǐng)求和響應(yīng)中都會(huì)發(fā)送關(guān)于請(qǐng)求的冗余信息,比如使用 Cookie 進(jìn)行用戶狀態(tài)的驗(yàn)證昭雌。
websocket特點(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)借助了http協(xié)議的一次握手建立連接宫盔。
前端實(shí)現(xiàn)
const pre = "wss:" // 或"ws:"
// 拼接url
const surl = `${pre}${url}`
// 校驗(yàn)瀏覽器是否支持websocket
if (typeof WebSocket === "undefined") {
return
}
const websocket = new WebSocket(surl)
// console.log(websocket.readyState) // 0
// readyState
// 0 鏈接還沒有建立(正在建立鏈接)
// 1 鏈接建立成
// 2 鏈接正在關(guān)閉
// 3 鏈接已經(jīng)關(guān)閉
// 如果鏈接成功建立融虽,向服務(wù)器發(fā)送消息
if(websocket.readyState === 1){
sendMessage(data)
// 否則一秒后重新嘗試(此步需要遞歸,這里只展示思路)
} else if (websocket.readyState === 0) {
setTimeOut(() => {
if(websocket.readyState === 1){
sendMessage(data)
}
}, 1000)
}
if(websocket.readyState === 3){
console.log("鏈接異常灼芭,請(qǐng)稍后重試")
// 進(jìn)入錯(cuò)誤處理
onError()
}
const sendWebsocket = ({
url,
params = {},
onMessage,
onError,
}) => {
// 監(jiān)聽鏈接開啟
websocket.onopen = () => {
console.log("--open--")
}
// 監(jiān)聽消息
websocket.onmessage= (e) => {
console.log(e)
// do something
onMessage();
}
// 監(jiān)聽錯(cuò)誤
websocket.onerror= (e) => {
console.log(e)
// do something
onError()
}
// 監(jiān)聽關(guān)閉狀態(tài)
websocket.onerror= (e) => {
console.log(e)
// do something
}
}
// 向服務(wù)端發(fā)送數(shù)據(jù)
const sendMessage = (data) => {
websocket.send(JSON.stringify(data))
}
// 請(qǐng)求關(guān)閉連接
const closeWebsocket = () => {
websocket.close()
}
websocket在前端一共有四種監(jiān)聽回調(diào): onopen有额、onmessage、onerror、onclose, 也就是開啟巍佑、有服務(wù)端發(fā)來(lái)消息茴迁、有錯(cuò)誤發(fā)生、關(guān)閉
websocket需要先建立連接句狼,再手動(dòng)調(diào)用.send方法向服務(wù)端發(fā)送數(shù)據(jù)笋熬。