简易websocket 聊天demo

·  阅读 788

这两天在看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)
复制代码

后续继续完善,看是否能够发送二进制图片,语音等信息!

分类:
前端
标签:
分类:
前端
标签: