使用Node.js 包含的ws模块来实现实时通讯的功能
第一次接触实时通讯,而且是自己利用空闲时间去了解websocket,偶然见看到了Node.js的ws模块,就突然觉得,原来实现实时通讯也不是很难。
Node.js代码
const http = require('http')
const express = require('express')
const app = express()
const server = http.createServer(app);
// 前台需要连接服务器,所以肯定要涉及到跨域问题
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.set('Content-Type', 'application/json');
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
res.setHeader('Pragma', 'no-cache')
res.setHeader('Expires', '0')
next();
});
// 引用 ws 模块
const ws = require('ws')
// 创建ws连接
var wss = new ws.Server({server})
wss.on("connection",function(socket){
socket.on("message",function(msg){ // msg是 onmessage接收到前台发送过来的内容
// wss.clients 获取现在所有连接的客户端,遍历循环,群发信息
wss.clients.forEach(function each(client) {
// readystate 遍历出用户现在的连接状态,如果属于连接状态,则使用send发送信息,将接收到的内容群发给每一个客户端
if (client.readyState === ws.OPEN) {
console.log(msg)
client.send(msg); // 发送
}
});
})
// 连接关闭执行的方法
socket.on("close",function(){
// 关闭当前连接
socket.close()
console.log('断开一人');
})
})
server.listen(3000, () => {
console.log('服务器已开启')
})
vue代码
<template>
<div style="padding: 50px;">
<input type="text" v-model="chat_content"> // 要发送的内容
<button @click="sendChat()">发送</button>
<ul>
<li v-for="(chat_item, index) in chat_list" :key="'chat_item' + index"> // 展示接收的消息
{{chat_item}}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Home',
data(){
return {
chat_content: '', // 输入框内容
chat_list: [], // 用来存储接收到的消息
ws: '' // 用于定义ws
}
},
methods: {
sendChat(){
// 点击事件生效
let that = this
// readyState 判断ws的链接状态
if(that.ws.readyState === 1) { // 判断当前ws的连接状态 1是连接
that.ws.onopen = function() {
console.log("连接成功");
that.ws.send(that.chat_content) // send发送内容
that.chat_content = '' // 将输入框清空
}()
}
// 接收消息触发
that.ws.onmessage = function(msg) {
that.chat_list.push(msg.data) // 将接收到的消息添加到数组里边
}
},
},
created(){
var that = this
that.ws = new WebSocket("ws://localhost:3000/") // 创建ws连接
that.ws.onmessage = function(msg) {
that.chat_list.push(msg.data) // 接收消息
}
}
}
</script>
遇到的问题
我刚开始写的时候,把连接ws写到了点击事件里边,点击按钮的时候才去连接ws,这样的写法我发现两点问题:
1. 当你进到页面中,不点击按钮你是无法接收到消息的。
2. 点击发送,第一次会触发一次send事件,第二次会触发两次,第三次触发三次…(原因我愣是没找到,请教别人说,这样点击一次连接一次,有悖于ws的初衷,具体为什么他也不太清楚)