mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-13 01:50:53 +08:00
【修复】条件节点前fromNodeId传值问题
【修复】部署参数默认错误问题 【测设】部分项目代码结构 【同步】前端项目代码
This commit is contained in:
143
frontend/packages/vue/hooks/src/socket/index.ts
Normal file
143
frontend/packages/vue/hooks/src/socket/index.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import { ref } from 'vue'
|
||||
|
||||
export interface SocketOptions {
|
||||
autoReconnect?: boolean // 是否自动重连, 默认为 true
|
||||
middleware?: (data: any) => any // 数据中间件函数,支持原始数据处理,默认为直接返回,支持多个中间件
|
||||
maxReconnectAttempts?: number // 最大重连次数, 默认无限制
|
||||
reconnectDelay?: number // 重连延迟, 默认为3000ms
|
||||
heartbeatInterval?: number // 心跳间隔, 单位毫秒
|
||||
heartbeatMessage?: any // 心跳包消息
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 将对象参数拼接到 URL 上,返回新的 URL 字符串
|
||||
* @param url - 基础 URL(如 'https://example.com')
|
||||
* @param obj - 要拼接到 URL 上的对象参数(键值对)
|
||||
* @returns 拼接参数后的完整 URL 字符串
|
||||
*/
|
||||
export function setObjToUrlParams(url: string, obj: Record<string, any>): string {
|
||||
// 将对象的每一个键值对转换成 'key=value' 形式,并且对 value 做 URL 编码
|
||||
const paramsArray: string[] = Object.entries(obj).map(([key, value]) => {
|
||||
return `${String(key)}=${encodeURIComponent(String(value))}`
|
||||
})
|
||||
|
||||
// 将所有 'key=value' 形式的字符串用 '&' 符号连接起来,形成 URL 查询字符串
|
||||
const parameters: string = paramsArray.join('&')
|
||||
|
||||
// 判断原 URL 是否以 '?' 结尾
|
||||
const hasQuestionMarkAtEnd: boolean = /\?$/.test(url)
|
||||
|
||||
// 根据 URL 是否已经有 '?' 来决定如何拼接参数
|
||||
if (hasQuestionMarkAtEnd) {
|
||||
// 如果 URL 已经以 '?' 结尾,直接加参数
|
||||
return url + parameters
|
||||
} else {
|
||||
// 如果 URL 没有以 '?' 结尾,需要先去除可能的结尾 '/',然后加上 '?'
|
||||
const cleanUrl = url.replace(/\/?$/, '')
|
||||
return cleanUrl + '?' + parameters
|
||||
}
|
||||
}
|
||||
|
||||
export default function useSocket(url: string, options?: SocketOptions) {
|
||||
const {
|
||||
autoReconnect = true,
|
||||
reconnectDelay = 3000,
|
||||
middleware = (data: any) => data,
|
||||
maxReconnectAttempts,
|
||||
heartbeatInterval = 5000,
|
||||
heartbeatMessage = 'ping',
|
||||
} = options || {}
|
||||
|
||||
const socket = ref<WebSocket | null>(null)
|
||||
const connected = ref(false)
|
||||
const message = ref<any>(null)
|
||||
let manuallyDisconnected = false // 标记是否主动断开
|
||||
|
||||
// 新增重连计数与心跳定时器变量
|
||||
let reconnectAttempts = 0
|
||||
let heartbeatTimer: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
// 建立WebSocket连接
|
||||
const connect = () => {
|
||||
// 兼容检测:若当前环境不支持 WebSocket,则打印错误并退出
|
||||
if (typeof WebSocket === 'undefined') {
|
||||
console.error('WebSocket is not supported in this environment.')
|
||||
return
|
||||
}
|
||||
manuallyDisconnected = false // 重置主动断开标记
|
||||
// 清除之前的心跳定时器
|
||||
if (heartbeatTimer) {
|
||||
clearInterval(heartbeatTimer)
|
||||
heartbeatTimer = null
|
||||
}
|
||||
socket.value = new WebSocket(url)
|
||||
|
||||
// 连接成功的回调
|
||||
socket.value.onopen = () => {
|
||||
connected.value = true
|
||||
reconnectAttempts = 0 // 重置重连计数
|
||||
// 如果配置了心跳包,启动心跳定时器
|
||||
if (heartbeatInterval && heartbeatMessage !== undefined) {
|
||||
heartbeatTimer = setInterval(() => {
|
||||
if (socket.value && connected.value) {
|
||||
socket.value.send(heartbeatMessage)
|
||||
}
|
||||
}, heartbeatInterval)
|
||||
}
|
||||
}
|
||||
|
||||
// 收到消息后,使用中间件处理数据
|
||||
socket.value.onmessage = (event: MessageEvent) => {
|
||||
message.value = middleware(event.data)
|
||||
}
|
||||
|
||||
// 出现错误时打印日志
|
||||
socket.value.onerror = (error) => {
|
||||
console.error('WebSocket error:', error)
|
||||
}
|
||||
|
||||
// 关闭连接的回调,判断是否需要自动重连
|
||||
socket.value.onclose = () => {
|
||||
connected.value = false // 更新连接状态
|
||||
socket.value = null
|
||||
// 清除心跳定时器
|
||||
if (heartbeatTimer) {
|
||||
clearInterval(heartbeatTimer)
|
||||
heartbeatTimer = null
|
||||
}
|
||||
// 如果自动重连且未主动断开,则在延迟后重连
|
||||
if (autoReconnect && !manuallyDisconnected) {
|
||||
if (maxReconnectAttempts !== undefined) {
|
||||
if (reconnectAttempts < maxReconnectAttempts) {
|
||||
reconnectAttempts++
|
||||
setTimeout(() => connect(), reconnectDelay)
|
||||
}
|
||||
} else {
|
||||
setTimeout(() => connect(), reconnectDelay)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 主动断开连接,禁止自动重连
|
||||
const disconnect = () => {
|
||||
manuallyDisconnected = true // 标记为主动断开
|
||||
if (socket.value) {
|
||||
socket.value.close()
|
||||
}
|
||||
// 清除心跳定时器
|
||||
if (heartbeatTimer) {
|
||||
clearInterval(heartbeatTimer)
|
||||
heartbeatTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
// 发送数据方法,仅在连接状态时执行
|
||||
const send = (data: any) => {
|
||||
if (socket.value && connected.value) {
|
||||
socket.value.send(data)
|
||||
}
|
||||
}
|
||||
|
||||
return { socket, connect, disconnect, send, message, connected }
|
||||
}
|
||||
Reference in New Issue
Block a user