「本文正在参与技术专题征文Node.js进阶之路,点击查看详情」
前言
聊天室 是主要基于 node 、Socket 实现的,node提供消息服务、Socket提供长链接通信
视图 是用 vue3.0 cdn引入
Node.js发布于2009年5月,由Ryan Dahl开发,是一个基于Chrome V8引擎的JavaScript运行环境,使用了一个事件驱动、非阻塞式I/O模型,让JavaScript 运行在服务端的开发平台,它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
安装node
安装教程不细说,很简单,请移步至官网 nodejs.cn/download/
创建项目
- 新建文件夹,命名为MSG
mkdir MSG
- 初始化项目
cd MSG
npm init
...
...
// 后面按提示 依次填写即可
安装依赖,socket.io
npm i socket.io
创建服务
添加一个 serve.js 文件
// 初始化 `app`
var app = require('http').createServer(handler)
// 通过传入 `http` (HTTP 服务器) 对象初始化了 `socket.io` 的一个实例
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(3000);
// 记录用户信息 集合
let arr = {
}
// 作为 HTTP 服务器的回调函数
function handler (req, res) {
// 读取index.html 返回(后文会介绍index.html中的内容)
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
// 然后监听 `connection` 事件来接收 sockets, 并将连接信息打印到控制台。
io.on('connection', function (socket) {
socket.emit('init', { hello: 'world' });
// 初始化链接 记录用户信息
socket.on('init', function (data) {
arr[data.id] = {
user: data.id
}
});
// 监听消息
socket.on('msg', function (data) {
socket.broadcast.emit('news', data);
});
socket.on('disconnect', function (data) {
console.log(data)
});
});
创建视图
添加一个 index.html 文件
引入 cdn vue
引入 socket.io.js
/socket.io/socket.io.js 启动服务后才能获取到 node serve.js
页面有点丑,没有细弄,这里 的逻辑是,初次进入页面 要填写名称,同时生成 唯一id,绑定当前用户,存入本地缓存, 待后面进入时直接读取缓存
<!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>聊天</title>
<script src="https://unpkg.com/vue@next"></script>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<div id="app">
<!-- 注册 -->
<div v-if="!setup">
<div>名字: <input v-model="userInfo.name" /></div>
<button @click="register">提交</button>
</div>
<div v-else>
<div>uuid: {{userInfo.uuid}}</div>
<div>user: {{userInfo.name}}</div>
<div v-for="(item,index) in msgList" :key="index">{{item.name}}: {{item.msg}}</div>
<div><input v-model="msg" /> <button @click="submit">提交</button></div>
</div>
</div>
<script>
const app = Vue.createApp({
data() {
return {
count: 4,
ws:'',
msgList:[],
socket:null,
msg:'',
userInfo:{
uuid: '',
name:''
},
setup:false
}
},
mounted() {
// 检测本地缓存是否 已注册过
let userInfo = localStorage.getItem("userInfo");
// 读取缓存信息
if(userInfo){
this.userInfo = JSON.parse(userInfo)
this.setup = true
}else{
// 生成唯一id
this.userInfo.uuid = guid()
}
// 建立连接
let That = this
this.socket = io('http://localhost:3000');
// 监听 新消息 事件
this.socket.on('news', (data) => {
this.msgList = this.msgList.concat(data)
});
},
methods:{
// 发送消息
submit(){
if(!this.msg){
alert('不能为空')
return
}
let data = { name:this.userInfo.name, id: this.userInfo.uuid,msg:this.msg }
this.msgList = this.msgList.concat(data)
this.socket.emit('msg', data);
this.msg = ''
},
// 注册信息
register(){
if(!this.userInfo.name){
alert('不能为空')
return
}
this.setup = true
localStorage.userInfo = JSON.stringify(this.userInfo)
}
}
})
const vm = app.mount('#app')
// 生成唯一id
function guid() {
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}
</script>
</body>
</html>
初次写文章,有点生疏,如有不好之处,还望多多谅解