这两天在看websocket 的东西,于是跟着视频写了个简单的双向通信的聊天小案例,服务气端口用的是 nodemon 工具来来监听端口将js文件作为服务来启动,前端可以使用各种构建工具,例如webpack,rollup,vite 来启动服务,但由于这些工具都是用来打包项目的,我这边只是一个小案例用他们显得有些大材小用了,也可以使用nodemon 来启动文件作为静态服务器,但是为了多学多用,就用了 live-server. node的这两个库使用方法大同小异,就是使用该命令来监听制定目录下文件的变动。
live-server ./ --port=8888
nodemon ./index.js --port = 9999
基本概念
先总结下websocket 基本概念
服务器端: 服务器端主要是各个客户端传输过来的消息的分发,即(收集各个客户端发的消息,再广播给各个客户端);
客户端:客户端连接服务端的websocket服务器,然后发送消息给服务器
主要api有:
1.open
2.message
3.error
4.message
服务气短相比客户端api
1.open
2.close
3.error
4.connection -> message
5.connection 调用message 方法,调用 websocket 的clients 方法获取所有链接到该服务器的客户端,然后将接收到的消息通过,客户端.send(),广发给所有客户端
具体代码如下: index.js:
/*
* @Author: wwt
* @Date: 2021-07-12 11:08:27
* @LastEditors: wwt
* @LastEditTime: 2021-07-12 13:35:33
* @Description: file content
*/
(function(storage,doc){
const userName = doc.querySelector('#username');
const btn = document.querySelector('#enter');
const init = ()=>{
bindEvent();
}
const bindEvent = ()=>{
btn.addEventListener('click',handleEnter,false);
}
const handleEnter = ()=>{
const userNameVal = userName.value.trim();
if(!userNameVal){
window.alert('请输入用户名!')
}
storage.setItem('userName',userNameVal);
location.href = '../chat.html';
}
init();
})(localStorage,document)
server.js
/*
* @Author: wwt
* @Date: 2021-07-12 13:50:45
* @LastEditors: wwt
* @LastEditTime: 2021-07-12 16:22:11
* @Description: file content
*/
const ws = require('ws');
(function () {
const server = new ws.Server({ port: 8000 }); //可抽离成配置文件
const init = ()=> {
bindEvent();
}
const bindEvent = () =>{
server.on('open',handleOpen);
server.on('close',handleClose);
server.on('error',handleError);
server.on('connection',handleConnection);
}
const handleOpen = ()=>{
console.log('server --- ws open');
}
const handleClose = ()=>{
console.log('server --- ws close');
}
const handleError = ()=>{
console.log('server --- ws error');
}
const handleConnection = (ws)=>{
ws.on('message',handleMsg);
}
const handleMsg = (msg)=>{
console.log(msg,'server ==== msg');
server.clients.forEach(c=>{
c.send(msg); // 发给所有客户端
})
}
init();
})(ws)
chat.js
/*
* @Author: wwt
* @Date: 2021-07-12 13:36:50
* @LastEditors: wwt
* @LastEditTime: 2021-07-13 08:56:42
* @Description: file content
*/
(function(doc,storage){
const sendBtn = doc.querySelector('#sendBtn');
const inputMsg = doc.querySelector('#inputMsg');
const msgList = doc.querySelector('#msgList');
const ws = new WebSocket("ws:10.28.56.81:8000");
let userName = '';
const init = () =>{
bindEvent();
}
const bindEvent = ()=>{
sendBtn.addEventListener('click',sendMsg,false);
ws.addEventListener('open',handleOpen,false);
ws.addEventListener('close',handleClose,false);
ws.addEventListener('error',handleError,false);
ws.addEventListener('message',handleMessage,false);
}
const sendMsg = ()=>{
const msg = inputMsg.value.trim();
if(!msg){return}
//TODO
let data = {
user:userName,
time:new Date(),
message:msg,
}
ws.send(JSON.stringify(data));
inputMsg.value = '';
}
const handleOpen = ()=>{
userName = storage.getItem('userName');
//用户名不存在直接去入口页面
if(!userName){
location.href = '../index.html';
return;
}
console.log('ws open11---');
}
const handleClose = ()=>{
console.log('ws closed---');
}
const handleError = ()=>{
console.log('ws error--');
}
const handleMessage = (e)=>{
console.log(e.data,'server 发回来的message');
const msgData = JSON.parse(e.data);
msgList.appendChild(createMsg(msgData));
}
const createMsg = (data)=>{
const {user,time,message} = data;
const item = doc.createElement('div');
item.innerHTML = `
<p>
<span>${user}</span>
<i>${time}</i>
</p>
<p>消息: ${message}</p>
`
return item;
}
init();
})(document,localStorage)
后续继续完善,看是否能够发送二进制图片,语音等信息!