WebSocket
HTML5 新增的一個(gè)特性,可實(shí)現(xiàn) http 雙向通信
單向通信:服務(wù)端必須先接受到客戶端的請(qǐng)求,才能給客戶端回消息
基于 WebSocket 可實(shí)現(xiàn)的功能:
- 聊天室(這里舉例)
之前的實(shí)現(xiàn)方法:
- 張三、李四、王五,都加入了聊天室
- 每個(gè)人都與聊天室的服務(wù)器做 輪詢請(qǐng)求(setInterval)
- 張三向服務(wù)器發(fā)一個(gè)消息 hello
- 服務(wù)器等待下一次的李四、王五的請(qǐng)求過(guò)來(lái),接著把 hello 發(fā)送給李四、王五
基于 Websocket:
- 張三、李四、王五,都加入了聊天室
- 這三個(gè)人都與服務(wù)器建立起 ==雙向通信鏈接==
- 張三發(fā)一個(gè)消息
- 服務(wù)器接收到張三的消息后,主動(dòng)把消息轉(zhuǎn)發(fā)給李四、王五
- 股票交易網(wǎng)站
- 需要實(shí)時(shí)更新數(shù)據(jù)的
實(shí)現(xiàn)一個(gè) WebSocket 的聊天室
- 需要有服務(wù)端,使用 nodejs 的第三方模塊 ws 來(lái)實(shí)現(xiàn)服務(wù)端代碼
- 需要有客戶端,使用瀏覽器 HTML5
安裝ws模塊:npm install --save ws
//后端代碼 server.js
//1.引入
const WebSocket = require('ws');
//2.創(chuàng)建 ws 服務(wù)
const server = new WebSocket.Server({port:3000});
let index = 0; //用于標(biāo)記每個(gè)客戶端
let clients = [];//存放當(dāng)前連接到這個(gè)服務(wù)的所有客戶端對(duì)象
//3.監(jiān)聽客戶端的請(qǐng)求
server.on('connection', ws => { //這里的 ws 就是當(dāng)前連接進(jìn)來(lái)的 WebSocket 實(shí)例
console.log('客戶端連接起來(lái)了');
//1. 給當(dāng)前客戶端設(shè)置一個(gè) index 屬性
ws.index = ++index; //標(biāo)記客戶端
//2.將當(dāng)前客戶端 push 進(jìn) clients
clients.push(ws);
//ws 監(jiān)聽 message ,data客戶端發(fā)來(lái)的消息
ws.on('message',(data) => {
//將data這個(gè)消息發(fā)送給其他客戶端
//循環(huán)遍歷 clients 拿到其中所有客戶端對(duì)象,調(diào)用send方法把data發(fā)回去,注意排除當(dāng)前這個(gè)客戶端
clients.forEach(item => {
if(item.index !== ws.index){
item.send(`${ws.index} : ${data}`);
};
});
});
})
<!--前端頁(yè)面 必須為HTML5-->
<!--通過(guò)js代碼-->
<script>
//1.連接到服務(wù)
let ws = new WebSocket('ws://127.0.0.1:3000');
//2.監(jiān)聽 按鈕 點(diǎn)擊事件
let btn = document.getElementById('btn');//這是頁(yè)面中的按鈕
let input = document.getElementById('input');//這是頁(yè)面中的輸入框
let ulEl = document.getElementById('ul'); //dom緩存 避免多次獲取 頁(yè)面中的ul 數(shù)據(jù)體
btn.onclick = function(){ //發(fā)消息
let msgV = input.value;
ws.send(msgV);
};
//3.監(jiān)聽 服務(wù)端的消息 后渲染頁(yè)面
ws.onmessage = function (event){
let msg = event.data;
let liEl = document.createElement('li');
};
</script>