项目设计方案
涉及技术
WebSocket+socket.io+express+parcel+Javascript+CSS+HTML
WebSocket
一、WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算)
首先HTTP有1.1和1.0之说,也就是所谓的keep-alive,把多个HTTP请求合并为一个,但是Websocket其实是一个新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已,也就是说它是HTTP协议上的一种补充可以通过这样一张图理解
有交集,但是并不是全部。
另外Html5是指的一系列新的API,或者说新规范,新技术。Http协议本身只有1.0和1.1,而且跟Html本身没有直接关系。。
通俗来说,你可以用HTTP协议传输非Html数据
再简单来说,层级不一样。
二、Websocket是什么样的协议,具体有什么优点
首先,Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说。
简单的举个例子吧,用目前应用比较广泛的PHP生命周期来解释。
1) HTTP的生命周期通过Request来界定,也就是一个Request 一个Response,那么在HTTP1.0中,这次HTTP请求就结束了。
在HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。
但是请记住 Request = Response , 在HTTP中永远是这样,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。
websocket简单示例
// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
Express
Express 是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架,它提供一系列强大的特性,帮助你创建各种 Web 和移动设备应用。
Express 不对 Node.js 已有的特性进行二次抽象,我们只是在它之上扩展了 Web 应用所需的基本功能。
Parcel
Parcel 是 Web 应用打包工具,适用于经验不同的开发者。它利用多核处理提供了极快的速度,并且不需要任何配置。
首先通过 Yarn 或者 npm 安装 Parcel :
Yarn:
yarn global add parcel-bundler
npm:
npm install -g parcel-bundler
在你正在使用的项目目录下创建一个 package.json 文件:
yarn init -y
or
npm init -y
Parcel 可以使用任何类型的文件作为入口,但是最好还是使用 HTML 或 JavaScript 文件。如果在 HTML 中使用相对路径引入主要的 JavaScript 文件,Parcel 也将会对它进行处理将其替换为相对于输出文件的 URL 地址。
整体架构
项目分为client和server两部分,两者通过该socket通信。
支持群组聊天,也就是多个用户在一个聊天室聊天。消息同步从进入聊天室到当前时间聊天室中的所有消息。
运行效果
聊天室界面
项目源代码分析
Server端
登录聊天服务器
流程图如下所示:
不支持在 Docs 外粘贴 block
相关代码如下所示:
// 登录
socket.on('login', function (data) {
if (users.indexOf(data.name) >= 0) {
console.log(data.name + ' 已有重名用户,请重新输入昵称。')
socket.emit('login', {
status: 'err',
text: '已有重名用户,请重新输入昵称。'
})
} else {
// 添加一个用户
users.push(data.name)
// 设置当前用户的 nickName
socket.nickName = data.name
console.log(data.name + ' 进入了房间')
console.log('当前用户', users)
// 发送进入房间的通知
io.emit('sys', {
text: socket.nickName + ' 进入了房间',
count: users.length,
users: users
})
// 发送登录成功的通知
socket.emit('login', {
status: 'ok'
})
}
})
广播信息
服务器每次接收到的信息要广播给除自己外的所有人。
相关代码如下所示:
// 接收发送信息后广播给除自己外的所有人
socket.on('message', function (data) {
socket.broadcast.emit('message', data)
})
Client端
主要代码是发送消息这一块儿,消息不能为空,内容不能超过30个字,通过socket提交
// 发送消息?
function sendMessage () {
let oText = document.getElementById('js-text')
let sText = delHtmlTag(oText.value)
if (sText === '') {
alert('不能为空')
return false
} else if (sText.length > 30) {
alert('内容不能超过30个字')
return false
}
socket.emit('message', {
name: nickName,
text: sText
})
oMessageBox.innerHTML += `<li class="my">
<div class="name">${nickName}</div>
<div class="message">${sText}</div>
</li>`
oText.value = ''
oMessageBox.scrollTop = oMessageBox.scrollHeight
}
oEnter.addEventListener('click', sendMessage)
document.getElementById('js-text').addEventListener('keydown', function () {
if (event.key === 'Enter') {
sendMessage()
}
})
参考文献
WebSocket 是什么原理?为什么可以实现持久连接? - 知乎
WebSocket - Web API 接口参考 | MDN
Express - api参考
🚀 快速开始 | Parcel 中文网