导出方法为sse
This commit is contained in:
parent
199dd3ddb4
commit
800c93602e
@ -13,6 +13,9 @@ VUE_APP_API_DEV = https://dev.api.linkwing.com/api/v1
|
|||||||
VUE_APP_WS_URL = wss://dev.api.linkwing.com/wss
|
VUE_APP_WS_URL = wss://dev.api.linkwing.com/wss
|
||||||
VUE_APP_WSS_URL = wss://dev.api.linkwing.com/wss
|
VUE_APP_WSS_URL = wss://dev.api.linkwing.com/wss
|
||||||
|
|
||||||
|
# SSE地址
|
||||||
|
VUE_APP_SSE_URL = https://dev.api.linkwing.com/sse/stream
|
||||||
|
|
||||||
# 本地端口
|
# 本地端口
|
||||||
VUE_APP_PORT = 2801
|
VUE_APP_PORT = 2801
|
||||||
|
|
||||||
|
|||||||
@ -5,15 +5,15 @@ NODE_ENV = production
|
|||||||
VUE_APP_TITLE = 象纬云科
|
VUE_APP_TITLE = 象纬云科
|
||||||
|
|
||||||
# 测试环境
|
# 测试环境
|
||||||
VUE_APP_API_BASEURL = https://dev.api.linkwing.com/api/v1
|
# VUE_APP_API_BASEURL = https://dev.api.linkwing.com/api/v1
|
||||||
VUE_APP_API_DEV = https://dev.api.linkwing.com/api/v1
|
# VUE_APP_API_DEV = https://dev.api.linkwing.com/api/v1
|
||||||
VUE_APP_WS_URL = wss://dev.api.linkwing.com/wss
|
# VUE_APP_WS_URL = wss://dev.api.linkwing.com/wss
|
||||||
VUE_APP_WSS_URL = wss://dev.api.linkwing.com/wss
|
# VUE_APP_WSS_URL = wss://dev.api.linkwing.com/wss
|
||||||
|
|
||||||
# 线上环境
|
# 线上环境
|
||||||
# 接口地址 # WS地址
|
# 接口地址 # WS地址
|
||||||
# VUE_APP_API_BASEURL = https://prod.api.linkwing.com/api/v1
|
VUE_APP_API_BASEURL = https://prod.api.linkwing.com/api/v1
|
||||||
# VUE_APP_API_DEV = https://prod.api.linkwing.com/api/v1
|
VUE_APP_API_DEV = https://prod.api.linkwing.com/api/v1
|
||||||
# VUE_APP_WS_URL = wss://prod.api.linkwing.com/wss
|
VUE_APP_WS_URL = wss://prod.api.linkwing.com/wss
|
||||||
# VUE_APP_WSS_URL = wss://prod.api.linkwing.com/wss
|
VUE_APP_WSS_URL = wss://prod.api.linkwing.com/wss
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,11 @@
|
|||||||
<div :class="list.length-1==index?'':'exportItem'" v-if="list.length>0 && type == item.type">
|
<div :class="list.length-1==index?'':'exportItem'" v-if="list.length>0 && type == item.type">
|
||||||
<div class="exportHeader">
|
<div class="exportHeader">
|
||||||
<div class="name">{{item.type_desc}}</div>
|
<div class="name">{{item.type_desc}}</div>
|
||||||
<div class="status" v-if="item.status==0">{{item.msg}}</div>
|
<div class="status" v-if="item.status==0">
|
||||||
|
<el-tooltip effect="dark" :content="item.msg">
|
||||||
|
<span size="mini">{{item.msg}}</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
<div class="finish" v-if="item.status==1"><i class="icon"><sc-icon-Finish/></i> 文件生成完成</div>
|
<div class="finish" v-if="item.status==1"><i class="icon"><sc-icon-Finish/></i> 文件生成完成</div>
|
||||||
</div>
|
</div>
|
||||||
<el-progress class="exportPopover" :text-inside="true" :stroke-width="12" :percentage="item.rate" />
|
<el-progress class="exportPopover" :text-inside="true" :stroke-width="12" :percentage="item.rate" />
|
||||||
@ -24,27 +28,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
|
|
||||||
<!-- <div class="customerPopover">-->
|
|
||||||
<!-- <div class="btnBox">-->
|
|
||||||
<!-- <slot></slot>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <div class="contentPopover" v-if="show">-->
|
|
||||||
<!-- <div class="bodyMain">-->
|
|
||||||
<!-- <span class="arrow"></span>-->
|
|
||||||
<!-- <div v-for="(item,index) in list" :key="item">-->
|
|
||||||
<!-- <div :class="list.length-1==index?'':'exportItem'" v-if="list.length>0 && type == item.type">-->
|
|
||||||
<!-- <div class="exportHeader">-->
|
|
||||||
<!-- <div class="name">{{item.type_desc}}</div>-->
|
|
||||||
<!-- <div class="status" v-if="item.status==0">{{item.msg}}</div>-->
|
|
||||||
<!-- <div class="finish" v-if="item.status==1"><i class="icon"><sc-icon-Finish/></i> 文件生成完成</div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <el-progress class="exportPopover" :text-inside="true" :stroke-width="12" :percentage="item.rate" />-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -77,10 +60,14 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// 获取新消息
|
// 获取新消息
|
||||||
eventBus.$on('sockBack', this.getWsResult);
|
// eventBus.$on('sockBack', this.getWsResult);
|
||||||
|
|
||||||
|
eventBus.$on('sseBack', this.getWsResult);
|
||||||
},
|
},
|
||||||
unmounted() {
|
unmounted() {
|
||||||
eventBus.$off('sockBack', this.getWsResult);
|
// eventBus.$off('sockBack', this.getWsResult);
|
||||||
|
|
||||||
|
eventBus.$off('sseBack', this.getWsResult);
|
||||||
},
|
},
|
||||||
methods:{
|
methods:{
|
||||||
getWsResult(res){
|
getWsResult(res){
|
||||||
|
|||||||
@ -10,7 +10,11 @@
|
|||||||
<div v-if="list.length>0 && type == item.type">
|
<div v-if="list.length>0 && type == item.type">
|
||||||
<div class="exportHeader">
|
<div class="exportHeader">
|
||||||
<div class="exportName">{{item.type_desc}}</div>
|
<div class="exportName">{{item.type_desc}}</div>
|
||||||
<div class="status" v-if="item.status==0">{{item.msg}}</div>
|
<div class="status" v-if="item.status==0">
|
||||||
|
<el-tooltip effect="dark" :content="item.msg">
|
||||||
|
<span size="mini">{{item.msg}}</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
<div class="finish" v-if="item.status==1"><i class="icon"><sc-icon-Finish/></i> 文件生成完成</div>
|
<div class="finish" v-if="item.status==1"><i class="icon"><sc-icon-Finish/></i> 文件生成完成</div>
|
||||||
</div>
|
</div>
|
||||||
<el-progress class="exportPopover" :text-inside="true" :stroke-width="12" :percentage="item.rate" />
|
<el-progress class="exportPopover" :text-inside="true" :stroke-width="12" :percentage="item.rate" />
|
||||||
@ -40,10 +44,14 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// 获取新消息
|
// 获取新消息
|
||||||
eventBus.$on('sockBack', this.getWsResult);
|
// eventBus.$on('sockBack', this.getWsResult);
|
||||||
|
// sse 获取新消息
|
||||||
|
eventBus.$on('sseBack', this.getWsResult);
|
||||||
},
|
},
|
||||||
unmounted() {
|
unmounted() {
|
||||||
eventBus.$off('sockBack', this.getWsResult);
|
// eventBus.$off('sockBack', this.getWsResult);
|
||||||
|
|
||||||
|
eventBus.$off('sseBack', this.getWsResult);
|
||||||
},
|
},
|
||||||
methods:{
|
methods:{
|
||||||
getWsResult(res){
|
getWsResult(res){
|
||||||
|
|||||||
@ -107,9 +107,13 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
eventBus.$on('sockBack', this.getWsResult);
|
eventBus.$on('sockBack', this.getWsResult);
|
||||||
|
|
||||||
|
// eventBus.$on('sseBack', this.getWsResult);
|
||||||
},
|
},
|
||||||
unmounted() {
|
unmounted() {
|
||||||
eventBus.$off('sockBack', this.getWsResult);
|
eventBus.$off('sockBack', this.getWsResult);
|
||||||
|
|
||||||
|
// eventBus.$off('sseBack', this.getWsResult);
|
||||||
},
|
},
|
||||||
methods:{
|
methods:{
|
||||||
getWsResult(res){
|
getWsResult(res){
|
||||||
|
|||||||
@ -23,6 +23,8 @@ const DEFAULT_CONFIG = {
|
|||||||
? process.env.VUE_APP_WS_URL
|
? process.env.VUE_APP_WS_URL
|
||||||
: process.env.VUE_APP_WSS_URL,
|
: process.env.VUE_APP_WSS_URL,
|
||||||
|
|
||||||
|
// SSE接口地址
|
||||||
|
SSE_URL:process.env.VUE_APP_SSE_URL,
|
||||||
//请求超时
|
//请求超时
|
||||||
TIMEOUT: 10000000,
|
TIMEOUT: 10000000,
|
||||||
|
|
||||||
|
|||||||
@ -262,9 +262,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
let token = this.$TOOL.cookie.get('TOKEN');
|
||||||
|
if(token && token !== null){
|
||||||
|
this.$seeApi.default.connect();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
unmounted() {
|
unmounted() {
|
||||||
|
this.$seeApi.default.close();
|
||||||
|
|
||||||
eventBus.$off('sockBack', this.getWsResult);
|
eventBus.$off('sockBack', this.getWsResult);
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import errorHandler from './utils/errorHandler'
|
|||||||
import * as elIcons from '@element-plus/icons-vue'
|
import * as elIcons from '@element-plus/icons-vue'
|
||||||
import * as scIcons from './assets/icons'
|
import * as scIcons from './assets/icons'
|
||||||
import * as socketApi from "@/utils/websocket";
|
import * as socketApi from "@/utils/websocket";
|
||||||
|
import * as sseApi from "@/utils/sseService";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install(app) {
|
install(app) {
|
||||||
@ -62,6 +63,7 @@ export default {
|
|||||||
app.config.globalProperties.$AUTH = permission;
|
app.config.globalProperties.$AUTH = permission;
|
||||||
app.config.globalProperties.$ROLE = rolePermission;
|
app.config.globalProperties.$ROLE = rolePermission;
|
||||||
app.config.globalProperties.$socketApi = socketApi;
|
app.config.globalProperties.$socketApi = socketApi;
|
||||||
|
app.config.globalProperties.$seeApi = sseApi;
|
||||||
|
|
||||||
//注册全局组件
|
//注册全局组件
|
||||||
app.component('scTable', scTable);
|
app.component('scTable', scTable);
|
||||||
|
|||||||
133
src/utils/sseService.js
Normal file
133
src/utils/sseService.js
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// src/utils/sse.js
|
||||||
|
// import store from "../store";
|
||||||
|
import tool from "@/utils/tool";
|
||||||
|
import systemConfig from '@/config';
|
||||||
|
import {eventBus} from "@/utils/eventBus";
|
||||||
|
|
||||||
|
let eventSource = null;
|
||||||
|
let reconnectTimer = null;
|
||||||
|
const reconnectDelay = 5000;
|
||||||
|
let isConnected = false;
|
||||||
|
let lockReconnect = false;
|
||||||
|
const callbacks = new Map();
|
||||||
|
const url = systemConfig.SSE_URL;
|
||||||
|
|
||||||
|
// 改进的连接管理
|
||||||
|
function createSSE(token) {
|
||||||
|
if (isConnected && eventSource) return;
|
||||||
|
|
||||||
|
closeSSE();
|
||||||
|
|
||||||
|
try {
|
||||||
|
let reToken = token === undefined ? tool.cookie.get('TOKEN') : token;
|
||||||
|
if(!reToken) return;
|
||||||
|
eventSource = new EventSource(`${url}?token=${reToken}`);
|
||||||
|
|
||||||
|
// 使用具名函数以便于移除监听器
|
||||||
|
eventSource.onopen = onOpen;
|
||||||
|
eventSource.onmessage = onMessage;
|
||||||
|
eventSource.onerror = onError;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('创建SSE连接失败:', error);
|
||||||
|
handleDisconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具名事件处理函数
|
||||||
|
function onOpen() {
|
||||||
|
isConnected = true;
|
||||||
|
console.log('SSE连接已建立');
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMessage(event) {
|
||||||
|
try {
|
||||||
|
const res = JSON.parse(event.data);
|
||||||
|
// store.commit('set_sse_msg', data);
|
||||||
|
if(res && res.data){
|
||||||
|
eventBus.$emit('sseBack',res.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析SSE数据失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onError() {
|
||||||
|
// error
|
||||||
|
// console.error('SSE连接错误:', error);
|
||||||
|
handleDisconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改进的注册方法
|
||||||
|
function registerCallback(callback, identifier = 'default') {
|
||||||
|
// 清理同名的旧回调
|
||||||
|
if (callbacks.has(identifier)) {
|
||||||
|
callbacks.delete(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
callbacks.set(identifier, {
|
||||||
|
fn: callback,
|
||||||
|
// 存储调用栈信息便于调试
|
||||||
|
_debug: new Error().stack.split('\n').slice(1, 4).join('\n')
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
callbacks.delete(identifier);
|
||||||
|
console.log(`SSE回调 ${identifier} 已取消注册`);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDisconnect() {
|
||||||
|
if (!isConnected) return;
|
||||||
|
|
||||||
|
isConnected = false;
|
||||||
|
// console.log('SSE连接断开,尝试重连...');
|
||||||
|
|
||||||
|
if (!lockReconnect) {
|
||||||
|
lockReconnect = true;
|
||||||
|
clearTimeout(reconnectTimer);
|
||||||
|
reconnectTimer = setTimeout(() => {
|
||||||
|
lockReconnect = false;
|
||||||
|
// 重连时保留现有回调
|
||||||
|
createSSE();
|
||||||
|
}, reconnectDelay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function restartSSE(token) {
|
||||||
|
closeSSE();
|
||||||
|
createSSE(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeSSE() {
|
||||||
|
if (eventSource) {
|
||||||
|
// 移除所有监听器
|
||||||
|
eventSource.onopen = null;
|
||||||
|
eventSource.onmessage = null;
|
||||||
|
eventSource.onerror = null;
|
||||||
|
|
||||||
|
eventSource.close();
|
||||||
|
eventSource = null;
|
||||||
|
}
|
||||||
|
isConnected = false;
|
||||||
|
clearTimeout(reconnectTimer);
|
||||||
|
console.log('SSE连接已关闭');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加调试方法
|
||||||
|
function debugCallbacks() {
|
||||||
|
callbacks.forEach((value, key) => {
|
||||||
|
console.log(`回调标识: ${key}`);
|
||||||
|
});
|
||||||
|
console.groupEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
connect: createSSE,
|
||||||
|
onMessage: registerCallback,
|
||||||
|
close: closeSSE,
|
||||||
|
restart: restartSSE,
|
||||||
|
debug: debugCallbacks,
|
||||||
|
get isConnected() {
|
||||||
|
return isConnected;
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user