作为一名有追求的码农来说,不管是前端、后端、抑或是测试、运维,都需要保持一定的好奇心才可以,那么大家都知道Vue作为前端框架的集大成者,拥有着易用、灵活和高效的优点,那么对于在Vue项目中集成WebSocket,大家有没有实践过呢?今天我为大家分享一下如何在Vue项目中集成WebSocket。
开发环境
- Window 10.0.17763
- Node 10.18.0
- Visual Studio Code 1.48.2
- Vue 2.6.12
特别说明
本项目使用
SockJS-Client
和STOMP.js
来支持WebSocket后端(Node.js、Java等),在支持WebSocket的浏览器中可以直接进行连接、消息收发和端口等操作(详细内容请参考相关文档)。
接入步骤
添加依赖
我们在项目的入库页面(index.html
)中通过CDN的方式引入SockJS-Client
和STOMP.js
,文件内容如下。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="renderer" content="webkit" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
/>
<title>信息管理系统</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.0/sockjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
<div id="app"></div>
</body>
</html>
在Vue文件中连接和关闭WebSocket
既然我们在项目的入口页面中引入了WebSocket相关库,那么挂载在app
下的Vue组件均可以使用STOMP
和SockJS
,此时我们在Vue的生命周期函数mounted
、和beforeDestroy
中分别调用WebSocket的初始化和销毁函数,在data中声明WebSocket连接的Host
、Topic
等相关变量,下面给出Vue文件的内容如下。
<template>
<div class="app-container">
<el-row>
<el-col>
<search @getTableData="getTableData" @deleteSelected="remove"></search>
</el-col>
</el-row>
<el-row>
<el-col>
<Table @search="search" :data="gridData" :table="table" :pageParams="pageParams" :pageSizes="[10, 20, 50]" @getSelected="getSelected"></Table>
</el-col>
<el-button @click="sendMessage">发送消息</el-button>
</el-row>
</div>
</template>
<script>
import {
list,
save
} from "@/api/dashboard/enterprise/myMessage";
import Table from "@/components/table";
import to from "@/to";
import {
getToken
} from "@/utils/auth";
import search from "./search";
import {
mapState,
mapActions
} from "vuex";
const moment = require("moment");
export default {
name: "MesageList",
components: {
Table,
search
},
data: function () {
return {
table: {
// 行定义
columns: [{
prop: "content",
label: "消息内容",
width: ""
},
{
prop: "sender",
label: "发送者",
width: ""
},
{
prop: "typeName",
label: "消息类型",
width: ""
}
],
total: 0
},
wsHost: "http://localhost:8080/websocket",
wsTopic: "/topic/greeting",
websocket: null,
stompClient: null,
isConnected: false,
message: {},
messages: [],
headers: {
Authorization: getToken()
}
};
},
computed: {
...mapState("dashboard/message/index", [
"editDialogVisible",
"editDialogTitle",
"gridData",
"pageParams",
"checkboxSelected",
"params",
"total",
"form"
])
},
mounted() {
this._initSockJs();
},
beforeDestroy() {
this._destroySockJs();
},
methods: {
...mapActions("dashboard/message/index", ["setStateData"]),
// 操作回调
action(obj) {
if (obj.methods === "delete") {
this.setStateData({
checkboxSelected: [obj.row]
});
this.remove();
}
},
// 删除
remove() {
if (this.checkboxSelected && this.checkboxSelected.length > 0) {
this.$confirm("此操作将永久删除, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(async () => {
let [err, res] = await to(deleteByIds(this.checkboxSelected));
if (err) {
throw new Error(err.message);
}
this.$message({
type: "success",
message: "删除成功"
});
this.getTableData();
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除"
});
});
}
},
// 查询
search(pageParams) {
this.setStateData({
pageParams: pageParams
});
this.getTableData();
},
// 选中回调
getSelected(multipleSelection) {
this.setStateData({
checkboxSelected: multipleSelection
});
},
// 获取数据
async getTableData() {
let response = await list(this.params, this.pageParams);
let gridData = response.data.list;
let total = response.data.total;
this.setStateData({
gridData: gridData
});
this.table.total = total;
},
_initSockJs() {
this.getTableData();
this.socket = new SockJS(this.wsHost);
this.stompClient = Stomp.over(this.socket);
// 订阅
this.stompClient.connect(this.headers, frame => {
console.log("WebSocket连接成功", frame);
this.isConnected = true;
// 广播
this.stompClient.subscribe(this.wsTopic, response => {
console.log("/websocket/message", JSON.parse(response.body));
this.messages.push(JSON.parse(response.body));
this.setStateData({
gridData: this.messages
});
});
// 一对一
this.stompClient.subscribe("/user/topic/greeting", response => {
console.log(
"/user/topic/greeting/message",
JSON.parse(response.body)
);
this.messages.push(JSON.parse(response.body));
this.setStateData({
gridData: this.messages
});
});
// 广播
this.stompClient.subscribe("/topic/greeting", response => {
console.log("/topic/greeting/message", JSON.parse(response.body));
this.messages.push(JSON.parse(response.body));
this.setStateData({
gridData: this.messages
});
});
});
},
_destroySockJs() {
if (this.stompClient != null) {
this.stompClient.disconnect();
this.socket.onclose;
this.socket.close();
this.stompClient = {};
this.socket = {};
this.isConnected = false;
}
console.log("WebSocket断开成功");
},
async sendMessage() {
this.message = {
sender: this.$store.getters.introduction,
type: "3",
content: "消息内容",
receiver: "*",
sendingDate: moment(new Date()).format("YYYY-MM-DD HH:mm:ss")
};
let [err, res] = await to(save(this.message));
if (err) {
throw new Error(err.message);
}
this.stompClient.send(this.wsTopic, {}, JSON.stringify(this.message));
this.$message({
showClose: true,
message: "消息发送成功",
type: "success"
});
}
}
};
</script>
sendMessage
函数用于测试消息发送,发送完消息后持久化消息并通过订阅的Topic即时收取消息,收到消息后保存到表格中。
getToken
函数是为了获取登录认证后保存的个人信息。
验证连接结果
我们启动前后端的项目,然后定位到该页面,打开开发者工具并切换到控制台,控制台会显示以下信息。
控制台结果 - 图片来自我的手机通过以上的截图我们可以得知WebSocket
连接的后端地址,心跳检测的输出和stompClient
的认证字段,那么急于此我们可以构建不同的应用场景,比如聊天、消息收发、任务提醒等功能,再配合其他功能来满足客户的诉求,我相信WebSocket
的接入会让你的应用更好用。
个人收获及感想
我们的文章今天为大家介绍了Vue项目中接入WebSocket的方法,通过连接、收发消息和断开等方法来接入WebSocket后端,接入之后就可以愉快地集成其他的业务啦。而在现在的复杂多变的产品迭代周期中,WebSocket不可或缺,并且会不断发展和变化,相信过不了多久,我们的产品也会慢慢完善,并趋于完美。让我们一起持续打造能满足客户诉求的好产品,持续为客户做好服务,成为更好的团队和更好的自己。
网友评论