websocket学习和群聊实现
WebSocket協(xié)議可以實(shí)現(xiàn)前后端全雙工通信,從而取代浪費(fèi)資源的長輪詢。在此協(xié)議的基礎(chǔ)上,可以實(shí)現(xiàn)前后端數(shù)據(jù)、多端數(shù)據(jù),真正的實(shí)時(shí)響應(yīng)。在學(xué)習(xí)WebSocket的過程中,實(shí)現(xiàn)了一個(gè)簡化版群聊,過程和代碼詳細(xì)記錄在這篇文章中。
本篇文章來自董沅鑫的個(gè)人網(wǎng)站,引用、轉(zhuǎn)載請指明出處。
查看更多知識,或者技術(shù)交流:請?jiān)L問godbmw.com
1 概述
1.1 WebSocket 是什么?
1.2 為什么需要 WebSocket?
了解計(jì)算機(jī)網(wǎng)絡(luò)協(xié)議的人,應(yīng)該都知道:HTTP 協(xié)議是一種無狀態(tài)的、無連接的、單向的應(yīng)用層協(xié)議。它采用了請求/響應(yīng)模型。通信請求只能由客戶端發(fā)起,服務(wù)端對請求做出應(yīng)答處理。
這種通信模型有一個(gè)弊端:HTTP 協(xié)議無法實(shí)現(xiàn)服務(wù)器主動向客戶端發(fā)起消息。
因此,如果在客戶端想實(shí)時(shí)監(jiān)聽服務(wù)器變化,必須使用 ajax 來進(jìn)行輪詢,效率低,浪費(fèi)資源。
而 websocket 就可以使得前后端進(jìn)行全雙工通信(兩方都可以向?qū)Ψ竭M(jìn)行數(shù)據(jù)推送),是真正的平等對話。
2 WebSocket 客戶端
支持HTML5的瀏覽器支持 WebSocket 協(xié)議:
var ws = new WebSocket(url); // 創(chuàng)建一個(gè)websocket對象2.1 WebSocket 屬性
| ws.readyState | 只讀屬性 readyState 表示連接狀態(tài),可以是以下值:0 - 表示連接尚未建立。1 - 表示連接已建立,可以進(jìn)行通信。2 - 表示連接正在進(jìn)行關(guān)閉。3 - 表示連接已經(jīng)關(guān)閉或者連接不能打開。 |
| ws.bufferedAmount | 只讀屬性 bufferedAmount 已被 send() 放入正在隊(duì)列中等待傳輸,但是還沒有發(fā)出的 UTF-8 文本字節(jié)數(shù)。 |
2.2 WebSocket 方法
| ws.send() | 數(shù)據(jù)發(fā)送 |
| ws.close() | 關(guān)閉連接 |
2.3 Websocket 事件
| open | 連接建立觸發(fā) |
| message | 通信時(shí)觸發(fā) |
| error | 出錯(cuò)觸發(fā) |
| close | 關(guān)閉連接觸發(fā) |
2.4 代碼實(shí)現(xiàn)
假設(shè)我們在本地8080端口打開了websocket服務(wù),那么,下面代碼可以在瀏覽器中實(shí)現(xiàn)和這個(gè)服務(wù)的通信:
<body><script>var ws = new WebSocket("ws://localhost:8080/");// 建立連接觸發(fā)ws.onopen = function () {ws.send("open ws");console.log("open ws");};// 接收服務(wù)端數(shù)據(jù)觸發(fā)ws.onmessage = function (evt) {var data = evt.data;console.log("Data is ", data);};// 斷開連接觸發(fā)ws.onclose = function () {console.log("close ws");};</script> </body>3 WebSocket 服務(wù)端
關(guān)于服務(wù)端實(shí)現(xiàn),根據(jù)技術(shù)選型不同,可以選用不同的庫和包。我這里使用的是node的ws庫來websocket服務(wù)端。
在阮一峰的博文提到的socket.io庫,在瀏覽器端的寫法不兼容原生API,準(zhǔn)確來說,它們自己實(shí)現(xiàn)了一套websocket。所以,使用的時(shí)候前后端都應(yīng)該引用第三方庫。這樣就造成了代碼遷移性,嚴(yán)重下降。
綜上所述,ws庫有以下優(yōu)點(diǎn):
4 實(shí)現(xiàn)群聊
4.1 群聊 服務(wù)端實(shí)現(xiàn)
首先,在命令行中,安裝ws庫: npm install ws --save
現(xiàn)在,利用ws來實(shí)現(xiàn)一個(gè)監(jiān)聽8080端口的websocket服務(wù)器,講解都在代碼注釋里,一目了然:
const PORT = 8080; // 監(jiān)聽端口 const WebSocket = require("ws"); // 引入 ws 庫const wss = new WebSocket.Server({ port: PORT }); // 聲明wss對象/*** 向除了本身之外所有客戶端發(fā)送消息,實(shí)現(xiàn)群聊功能* @param {*} data 要發(fā)送的數(shù)據(jù)* @param {*} ws 客戶端連接對象*/ wss.broadcastToElse = function broadcast(data, ws) { wss.clients.forEach(function each(client) {if (client !== ws && client.readyState === WebSocket.OPEN) {client.send(data);}}); };/* 客戶端接入,觸發(fā) connection */ wss.on("connection", function connection(ws, req) {let ip = req.connection.remoteAddress; // 通過req對象可以獲得客戶端信息,比如:ip,headers等/* 客戶端發(fā)送消息,觸發(fā) message */ws.on("message", function incoming(message) { ws.send(message); // 向客戶端發(fā)送消息wss.broadcastToElse(message, ws); // 向 其他的 客戶端發(fā)送消息,實(shí)現(xiàn)群聊效果});});4.2 群聊 客戶端實(shí)現(xiàn)
為了方便編寫,這里引入了jquery和bootstrap這兩個(gè)庫,只需要關(guān)注js代碼即可。
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>群聊</title><link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js"></script> </head> <body><div class="container"><textarea class="form-control" rows="30" disabled="disabled" id="show-area"></textarea><input type="text" class="form-control" placeholder="請輸入聊天內(nèi)容" id="chat-input"><button type="button" class="btn btn-info" id="send-btn">發(fā)送</button></div><script>var userName = parseInt(Math.random() * 1000, 10) // 隨機(jī)用戶名, 以標(biāo)識身份var sendBtn = $("#send-btn"), // 發(fā)送信息按鈕chatInput = $("#chat-input"), // 聊天信息輸入框showArea = $("#show-area") // 聊天信息展示框var ws = new WebSocket("ws://localhost:8080/") // 初始化WebSocket對象sendBtn.on("click", function () {var content = chatInput.val()if (content.length === 0) {return alert("請不要輸入空白內(nèi)容")}content = "At " + (new Date()).toString() + "\n" + "來自用戶" + userName + "\n" + content // 拼接用戶信息、時(shí)間信息和消息ws.send(content) // 發(fā)送消息chatInput.val("") // 清空輸入框})ws.onopen = function () { console.log("Conncet open") }ws.onmessage = function (evt) {var data = evt.datashowArea.val(showArea.val() + data + "\n\n") // 刷新聊天信息展示框:顯示群聊信息}ws.onclose = function () { console.log("Connect close") }</script> </body> </html>4.3 群聊 效果展示
首先啟動我們的服務(wù)端代碼:node server.js 。其中,server.js是放置服務(wù)端代碼的文件。
然后,我們打開2次編寫的html代碼,這相當(dāng)于,打開2個(gè)客戶端。來檢測群聊功能。
5. 相關(guān)資料
- 概念解釋:
- http://www.ruanyifeng.com/blog/2017/05/websocket.html
- https://www.cnblogs.com/jingmoxukong/p/7755643.html
- ws文檔:https://www.npmjs.com/package/ws
本篇文章來自董沅鑫的個(gè)人網(wǎng)站,引用、轉(zhuǎn)載請指明出處。
查看更多知識,或者技術(shù)交流:請?jiān)L問godbmw
轉(zhuǎn)載于:https://www.cnblogs.com/geyouneihan/p/9502280.html
總結(jié)
以上是生活随笔為你收集整理的websocket学习和群聊实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux后台运行打包Jar的方法
- 下一篇: 模型剖析 | 如何解决业务运维的四大难题