WebSocket 基础信息(前端部分)
WebSocket 状态
open
close
error
message
connection
前端常用的事件处理函数
open
close
error
message
后端常用的事件处理函数
open
close
error
message
connection
案例(原生 JS)
前端环境环境
1 2 3 4 5 6 7 8 9
| npm install -g yarn
mkdir chat-vue
cd chat-vue
npm init
yarn add vite -D
|
package.json 添加脚本命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| { "name": "chat-vue", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "vite" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "vite": "^3.1.0" } }
|
前端代码
enter 页面 即 登录页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input type="text" id="username" placeholder="请输入用户名" /> <button id="enter">进入聊天室</button> <script src="js/entry.js"></script> </body> </html>
|
entry 页面对应的 js 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| ;((doc, storage, location) => { const oUsername = doc.querySelector("#username"); const oEnterBtn = doc.querySelector("#enter");
const init = () => { bindEvent(); } function bindEvent () { oEnterBtn.addEventListener('click',handleEnterBtnClick, false); }
function handleEnterBtnClick () { const username = oUsername.value.trim();
if (username.length < 6) { alert('用户名不小于 6 位'); return; }
storage.setItem('username',oUsername); location.href = 'index.html'; }
init(); })(document, localStorage, location);
|
index 页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <ul id="list"></ul> <input type="text" id="message" placeholder="请输入消息" /> <button id="send">发送</button> <script src="js/index.js"></script> </body> </html>
|
index 页面对应的 js 文件 (主要是这边配置了 WebSocket )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| ;((doc,socket, storage,location) => {
const oList = doc.querySelector('#list'); const oMsg = doc.querySelector('#message'); const oSendBtn = doc.querySelector('#send'); const ws = new socket('ws:localhost:8000');
let username = '';
const init = () => { bindEvent(); }
function bindEvent () { oSendBtn.addEventListener('click', handleSendBtnClick, false); ws.addEventListener('open',handleOpen, false); ws.addEventListener('close',handleClose, false); ws.addEventListener('error', handleError, false); ws.addEventListener('message', handleMessage, false); }
function handleSendBtnClick (e) { console.log('send message',e);
const msg = oMsg.value;
if (!msg.trim().length) { return; }
ws.send( { user: username, dateTime: new Date().getTime(), message: msg } );
oMsg.value = '';
} function handleOpen(e) { console.log('websocket open',e); username = storage.getItem('username');
if (!username) { location.href = 'entry.html'; return; } }
function handleClose(e) { console.log('websocket close',e); }
function handleError(e) { console.log('websocket error',e); }
function handleMessage(e) { console.log('websocket message',e); const msgData = JSON.parse(e.data); oList.appendChild(createMsg(msgData)); }
function createMsg(data) { const { user, dateTime, message } = data; const oItem = doc.createElement('li'); oItem.innerHTML = ` <p> <span> ${ user } </span> <i>${ new Date(dateTime) }</i> </p> <p> 消息: ${ message } </p> `; return oItem; }
init();
})(document,WebSocket, localStorage, location);
|
配置 ws 后端服务
1 2 3 4 5 6 7 8 9
| mkdir server
cd server
npm init
yarn add ws
yarn add nodemon -g
|
配置启动命令 (使用 nodemon 去监控 index.js 文件)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { "name": "server", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "nodemon index.js" }, "author": "", "license": "ISC", "dependencies": { "nodemon": "^2.0.19", "ws": "^8.8.1" } }
|
index.js ws 服务后端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| const Ws = require('ws');
;((Ws) => { // 实例化 Websocket 的端口 // 访问地址:ws:localhost:8000 const server = new Ws.Server({ port: 8000 });
const init = () => { bindEvent(); }
function bindEvent() { server.on('open', handleOpen); server.on('close', handleClose); server.on('error', handleError); server.on('connection', handleConnection); }
function handleOpen() { console.log('Websocket open'); }
function handleClose() { console.log('WebSocket close'); }
function handleError() { console.log('WebSocket error'); }
function handleConnection(ws) {
console.log('WebSocket connection');
ws.on('message',handleMessage);
}
function handleMessage(msg) { console.log(msg.toString()); server.clients.forEach(function (c) { c.send(msg) })
}
init(); })(Ws);
|