在vue项目中使用stompjs+websocket进行封装实现订阅与发布功能
主要是为了记录一下实现封装的功能与方法
1.在你的项目里面src目录下新建一个api目录,目录里面建立一个stomp.js
**注意:**
// unsubscribe 对于取消订阅需要改一下源stompjs 路径:systemmonitor\views\node_modules\stompjs\lib\stomp.js
/*
* Client.prototype.unsubscribe = function(id,destination) {
* delete this.subscriptions[id];
* return this._transmit("UNSUBSCRIBE", {
* id: id,
* destination:destination
* });
* };
*/
bus.js代表全局消息总线,需要替换成自己的路径,里面的内容为如下:
import Vue from 'vue'
var bus = new Vue()
export default bus
引用需要的资源 ,store不做过多解释,就是vuex仓库,需要存连接状态
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
import bus from '@/components/common/bus';
import store from '@/vuex/store';
let host = window.location.host; //主机
// websocket地址
let baseStompUrl = 'ws://' + host;
// 公共地址 这个地方在开发环境下做了代理 需要改成自己的连接地址
let baseURL = process.env.NODE_ENV === 'development' ? (baseStompUrl+'/websocketApi/Parameters') : (baseStompUrl+'/Parameters');
let socket = null;
let stompClinent = null;
// 连接成功
const ConnectSuccess = (frame) => {
console.log('%c连接成功!', 'color:green;font-weight:bold;font-size:18px;', frame);
// 把当前是否连接成功的状态存起来,方便其他界面单独订阅判断是否是连接成功状态
store.commit('changestomp', true);
// 设备信息需要一直订阅
subscribeMessage('PushEquimentInfo');
}
// 连接失败
const ConnectError = (err) => {
//连接失败回调
console.log('%c连接失败!', 'color:red;font-weight:bold;font-size:18px;', err);
// 把当前是否连接成功的状态存起来,方便其他界面单独订阅判断是否是连接成功状态
stompClinent = null;
store.commit('changestomp', false);
let timerouts = setTimeout(() => {
initwebSocket();
clearTimeout(timerouts);
}, 5000);
}
// 建立连接
export const initwebSocket = () => {
// 建立连接对象
socket = new WebSocket(baseURL);
// 获取stomp子协议的客户端对象
stompClinent = Stomp.over(socket);
stompClinent.debug = true; //关闭调试模式
// 向服务器发起websocket连接并发送connect帧
stompClinent.connect({}, ConnectSuccess, ConnectError);
}
// 关闭连接
export const closeSocket = () => {
if (stompClinent != null) {
// 关闭连接
stompClinent.disconnect();
}
}
// 订阅上报信息
export const subscribeMessage= (str) =>{
if(str&&stompClinent){
stompClinent.subscribe(('/'+ str), res => {
if (isJson(res.body)) {
bus.$emit(str,JSON.parse(res.body))
}
}, { id:('sub-'+ str) });
}
}
// 取消上报信息
export const unsubscribeMessage= (str) =>{
if(str&&stompClinent){
stompClinent.unsubscribe(('sub-'+ str),('/'+ str) );
}
}
// 添加判断字符串是否是JSON格式的方法
function isJson(str) {
if (typeof str == 'string') {
try {
var obj = JSON.parse(str);
if (typeof obj == 'object' && obj) {
return true;
} else {
return false;
}
} catch (error) {
return false;
}
}
}
封装好以后在App.vue里面引用,初始化连接socket连接
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
// 创建连接订阅消息
import {initwebSocket,closeSocket} from '@/api/Stomp.js';
export default{
name:'App',
data() {
return {
isRouterAlive: true
}
},
mounted() {
// 建立连接
initwebSocket()
},
beforeDestroy() {
// 取消订阅 关闭连接
closeSocket();
},
methods: {
},
}
</script>
<style>
//这个地方是我外部引用的样式 不要全部copy 注意查看
@import "./assets/css/main.css";
@import "./assets/css/color-dark.css"; /*深色主题*/
/*@import "./assets/css/theme-green/color-green.css"; 浅绿色主题*/
</style>
然后在其他界面实现订阅与取消订阅方法调用
<script>
import { subscribeMessage, unsubscribeMessage } from '@/api/Stomp.js'
export default {
computed: {
// 监听长链接状态
stompStatus() {
return this.$store.state.stompStatus;
},
},
watch: {
stompStatus: {
handler(newVal, oldVal) {
if (newVal) {
// 如果连接成功就订阅数据
// 跟踪结果上报
subscribeMessage('PushMeasureResult');
}
},
deep: true,//深度监听
immediate: true,//立即执行
}
},
beforeDestroy() {
this.$Bus.$off('PushMeasureResult')
unsubscribeMessage('PushMeasureResult')
},
mounted(){
this.$Bus.on("PushMeasureResult", (res) => {
})
}
}
</script>