perf: 优化SSE连接
This commit is contained in:
parent
7c40b0dd40
commit
6dc2c40a64
@ -132,7 +132,7 @@ export default {
|
|||||||
// speedSmoothingFactor: 0.1,
|
// speedSmoothingFactor: 0.1,
|
||||||
// progressCallbacksInterval: 500,
|
// progressCallbacksInterval: 500,
|
||||||
maxChunkRetries: 3, // 最大重试次数
|
maxChunkRetries: 3, // 最大重试次数
|
||||||
simultaneousUploads: 5, // 并发上传数
|
simultaneousUploads: 2, // 并发上传数
|
||||||
testChunks: true, // 是否开启服务器分片校验
|
testChunks: true, // 是否开启服务器分片校验
|
||||||
// 服务器分片校验函数,秒传及断点续传基础
|
// 服务器分片校验函数,秒传及断点续传基础
|
||||||
checkChunkUploadedByResponse: function (chunk, message) {
|
checkChunkUploadedByResponse: function (chunk, message) {
|
||||||
@ -204,7 +204,7 @@ export default {
|
|||||||
message(msg) {
|
message(msg) {
|
||||||
switch (msg.event) {
|
switch (msg.event) {
|
||||||
case 'uploaderChunkSize':
|
case 'uploaderChunkSize':
|
||||||
this.onStorageTypeChange(msg.data)
|
this.onStorageTypeChange(msg.data.body)
|
||||||
break
|
break
|
||||||
case 'fileListScrollTop':
|
case 'fileListScrollTop':
|
||||||
this.fileListScrollTop = msg.data
|
this.fileListScrollTop = msg.data
|
||||||
|
|||||||
@ -43,7 +43,6 @@ export default {
|
|||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
data(val) {
|
data(val) {
|
||||||
console.log('data', val)
|
|
||||||
this.dataList = val
|
this.dataList = val
|
||||||
},
|
},
|
||||||
message(msg) {
|
message(msg) {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import ResizeMixin from './mixin/ResizeHandler'
|
|||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
import AudioPreview from "@/components/preview/AudioPreview";
|
import AudioPreview from "@/components/preview/AudioPreview";
|
||||||
import globalUploader from '@/components/SimpleUploader/globalUploader.vue'
|
import globalUploader from '@/components/SimpleUploader/globalUploader.vue'
|
||||||
import { connectToSSE } from '@/sse/SSEClient'
|
import { initiateSSE } from '@/sse/SSEClient'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Layout',
|
name: 'Layout',
|
||||||
@ -62,7 +62,7 @@ export default {
|
|||||||
if(getToken()){
|
if(getToken()){
|
||||||
this.isShow = window.pc;
|
this.isShow = window.pc;
|
||||||
// 与服务器建立sse连接
|
// 与服务器建立sse连接
|
||||||
connectToSSE(this.$store.state.user.name)
|
initiateSSE(this.$store.state.user.name)
|
||||||
if(this.$route.path.startsWith('/setting')){
|
if(this.$route.path.startsWith('/setting')){
|
||||||
this.isShow = true
|
this.isShow = true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,92 +1,108 @@
|
|||||||
import Bus from "@/assets/js/bus";
|
import Bus from "@/assets/js/bus";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import {generateUUID} from "ant-design-vue/lib/vc-select/util";
|
import { generateUUID } from "ant-design-vue/lib/vc-select/util";
|
||||||
|
|
||||||
let eventSource = null;
|
let eventSource = null;
|
||||||
let timer = null;
|
let timer = null;
|
||||||
let lastHeartbeat = new Date().getTime();
|
let lastHeartbeat = new Date().getTime();
|
||||||
|
|
||||||
const uuid = generateUUID();
|
const uuid = generateUUID();
|
||||||
|
|
||||||
const throttledConnectSSE = _.throttle(username => {
|
const throttledConnectSSE = _.throttle((username) => {
|
||||||
if (typeof (EventSource) !== 'undefined') {
|
if (typeof EventSource !== 'undefined') {
|
||||||
const url = `/api/events?username=${username}&uuid=${uuid}`;
|
connectToSSE(username);
|
||||||
eventSource = new EventSource(url);
|
|
||||||
eventSource.addEventListener('message', function (event) {
|
|
||||||
if (event.data === 'h') {
|
|
||||||
// 心跳包, 超过5s没有收到心跳包, 则关闭连接
|
|
||||||
lastHeartbeat = new Date().getTime()
|
|
||||||
} else {
|
|
||||||
const msg = JSON.parse( event.data);
|
|
||||||
onMessage(msg)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
eventSource.addEventListener('error', function (event) {
|
|
||||||
eventSource.close()
|
|
||||||
connectToSSE(username);
|
|
||||||
});
|
|
||||||
// 清除定时器
|
|
||||||
if (timer) {
|
|
||||||
clearInterval(timer);
|
|
||||||
}
|
|
||||||
// 3s检测一次连接状态
|
|
||||||
timer = setInterval(() => {
|
|
||||||
if (eventSource.readyState === 1) {
|
|
||||||
// 心跳包, 超过5s没有收到心跳包, 则关闭连接
|
|
||||||
if (new Date().getTime() - lastHeartbeat > 5000) {
|
|
||||||
eventSource.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (eventSource.readyState === 2) {
|
|
||||||
connectToSSE(username);
|
|
||||||
}
|
|
||||||
}, 3000);
|
|
||||||
} else {
|
} else {
|
||||||
console.error('EventSource is not supported by the browser');
|
console.error('EventSource is not supported by the browser');
|
||||||
}
|
}
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
export function connectToSSE(username) {
|
function connectToSSE(username) {
|
||||||
|
const url = `/api/events?username=${username}&uuid=${uuid}`;
|
||||||
|
eventSource = new EventSource(url);
|
||||||
|
|
||||||
|
eventSource.addEventListener('message', handleMessage);
|
||||||
|
eventSource.addEventListener('error', handleError.bind(null, username));
|
||||||
|
startHeartbeatCheck(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMessage(event) {
|
||||||
|
if (event.data === 'h') {
|
||||||
|
lastHeartbeat = new Date().getTime();
|
||||||
|
} else {
|
||||||
|
const msg = JSON.parse(event.data);
|
||||||
|
onMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleError(username) {
|
||||||
|
eventSource.close();
|
||||||
throttledConnectSSE(username);
|
throttledConnectSSE(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearExistingTimer() {
|
||||||
|
if (timer) {
|
||||||
|
clearInterval(timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startHeartbeatCheck(username) {
|
||||||
|
clearExistingTimer();
|
||||||
|
timer = setInterval(() => {
|
||||||
|
if (eventSource.readyState === 1 && new Date().getTime() - lastHeartbeat > 5000) {
|
||||||
|
eventSource.close();
|
||||||
|
}
|
||||||
|
if (eventSource.readyState === 2) {
|
||||||
|
throttledConnectSSE(username);
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
function onMessage(msg) {
|
function onMessage(msg) {
|
||||||
const url = msg.url
|
const { url, body } = msg;
|
||||||
if (url === 'synced') {
|
const eventMapping = {
|
||||||
store.dispatch('updateMessage', {event: 'msg/synced', data: msg})
|
synced: 'msg/synced',
|
||||||
} else if (url === 'taskProgress') {
|
taskProgress: 'msg/taskProgress',
|
||||||
store.dispatch('updateMessage', {event: 'msg/taskProgress', data: msg})
|
uploaderChunkSize: 'uploaderChunkSize',
|
||||||
} else if (url === 'uploaderChunkSize') {
|
};
|
||||||
store.dispatch('updateMessage', {event: 'uploaderChunkSize', data: msg.body})
|
|
||||||
|
if (eventMapping[url]) {
|
||||||
|
store.dispatch('updateMessage', { event: eventMapping[url], data: msg });
|
||||||
} else {
|
} else {
|
||||||
store.dispatch('updateMessage', {event: 'msg/file/change', data: msg})
|
handleFileChangeMessage(msg, url, body);
|
||||||
if ('operationFile' === url) {
|
}
|
||||||
let doc = msg.body
|
}
|
||||||
if (doc.code === 0) {
|
|
||||||
Bus.notify({
|
function handleFileChangeMessage(msg, url, body) {
|
||||||
title: `${doc.operation}成功`,
|
store.dispatch('updateMessage', { event: 'msg/file/change', data: msg });
|
||||||
dangerouslyUseHTMLString: true,
|
|
||||||
message: `
|
if (url === 'operationFile') {
|
||||||
<div>
|
const { operation, from, to, code, msg: message } = body;
|
||||||
<p>form:</p>
|
const notificationOptions = {
|
||||||
<pre style="word-break: break-all;white-space: pre-wrap;font-size: 12px;">${doc.from}</pre>
|
title: `${operation} ${code === 0 ? '成功' : '失败'}`,
|
||||||
</div>
|
dangerouslyUseHTMLString: true,
|
||||||
<div>
|
message: code === 0
|
||||||
<p>to:</p>
|
? `
|
||||||
<pre style="word-break: break-all;white-space: pre-wrap;font-size: 12px;">${doc.to}</pre>
|
<div>
|
||||||
</div>`,
|
<p>from:</p>
|
||||||
type: 'success',
|
<pre style="word-break: break-all;white-space: pre-wrap;font-size: 12px;">${from}</pre>
|
||||||
});
|
</div>
|
||||||
} else {
|
<div>
|
||||||
store.dispatch('updateMessage', {event: 'msg/file/operation/fault', data: msg});
|
<p>to:</p>
|
||||||
Bus.notify({
|
<pre style="word-break: break-all;white-space: pre-wrap;font-size: 12px;">${to}</pre>
|
||||||
title: `${doc.operation}失败`,
|
</div>`
|
||||||
dangerouslyUseHTMLString: true,
|
: `<span style="font-size: 12px;">${message}</span>`,
|
||||||
message: `<span style="font-size: 12px;">${doc.msg}</span>`,
|
type: code === 0 ? 'success' : 'error',
|
||||||
type: 'error'
|
};
|
||||||
});
|
|
||||||
}
|
Bus.notify(notificationOptions);
|
||||||
|
|
||||||
|
if (code !== 0) {
|
||||||
|
store.dispatch('updateMessage', { event: 'msg/file/operation/fault', data: msg });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function initiateSSE(username) {
|
||||||
|
throttledConnectSSE(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user