From cafb7ee07dd0fd5e93adf09d49ee1d185015eaeb Mon Sep 17 00:00:00 2001 From: u2nyakim Date: Thu, 28 Aug 2025 17:42:37 +0800 Subject: [PATCH] =?UTF-8?q?up.=20=E6=B7=BB=E5=8A=A0worker=E7=9A=84admin:wo?= =?UTF-8?q?rker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/command/admin/Worker.php | 8 +- ...{AdminWorker.php => AdminWorkerHandle.php} | 2 +- z_ele/src/main.ts | 17 ++ z_ele/src/plugins/WebSocketPlugin.ts | 218 ++++++++++++++++++ 4 files changed, 241 insertions(+), 4 deletions(-) rename app/http/worker/{AdminWorker.php => AdminWorkerHandle.php} (88%) create mode 100644 z_ele/src/plugins/WebSocketPlugin.ts diff --git a/app/command/admin/Worker.php b/app/command/admin/Worker.php index 92a6d96..0550091 100644 --- a/app/command/admin/Worker.php +++ b/app/command/admin/Worker.php @@ -3,7 +3,7 @@ namespace app\command\admin; -use app\http\worker\AdminWorker; +use app\http\worker\AdminWorkerHandle; use think\console\Command; use think\console\Input; use think\console\input\Argument; @@ -39,12 +39,14 @@ class Worker extends Command } else if ($mode == 'g') { $argv[] = '-g'; } + $handle = new AdminWorkerHandle(); + /* * 创建后台ws链接 */ $adminWorker = new WmWorker('ws://0.0.0.0:19980'); - $adminWorker->onMessage = [AdminWorker::class, 'onMessage']; - $adminWorker->onClose = [AdminWorker::class, 'onClose']; + $adminWorker->onMessage = [$handle, 'onMessage']; + $adminWorker->onClose = [$handle, 'onClose']; WmWorker::runAll(); } diff --git a/app/http/worker/AdminWorker.php b/app/http/worker/AdminWorkerHandle.php similarity index 88% rename from app/http/worker/AdminWorker.php rename to app/http/worker/AdminWorkerHandle.php index 7b3c3dd..8576aa0 100644 --- a/app/http/worker/AdminWorker.php +++ b/app/http/worker/AdminWorkerHandle.php @@ -1,7 +1,7 @@ = { + url: 'ws://139.155.146.146:19980', // 你的WebSocket服务器地址 + reconnectAttempts: 10, + reconnectDelay: 5000, + autoConnect: true // 应用启动时自动连接 +}; +// 安装WebSocket插件 +app.use(WebSocketPlugin, { + globalConfig: websocketConfig, + injectGlobal: true, + globalPropertyName: '$websocket' +}); + + app.use(store); app.use(router); app.use(permission); diff --git a/z_ele/src/plugins/WebSocketPlugin.ts b/z_ele/src/plugins/WebSocketPlugin.ts new file mode 100644 index 0000000..b9bea70 --- /dev/null +++ b/z_ele/src/plugins/WebSocketPlugin.ts @@ -0,0 +1,218 @@ +// plugins/WebSocketPlugin.ts +import { App, Plugin, ref, computed } from 'vue'; + +export enum ConnectionStatus { + CONNECTING = 'connecting', + CONNECTED = 'connected', + DISCONNECTED = 'disconnected', + ERROR = 'error' +} + +export enum MessageType { + INCOMING = 'incoming', + OUTGOING = 'outgoing', + SYSTEM = 'system' +} + +export interface WebSocketMessage { + content: string; + type: MessageType; + timestamp: Date; +} + +export interface WebSocketConfig { + url: string; + protocols?: string; + reconnectAttempts: number; + reconnectDelay: number; + autoConnect?: boolean; +} + +// 插件选项接口 +export interface WebSocketPluginOptions { + // 全局配置 + globalConfig?: Partial; + // 是否注入全局实例 + injectGlobal?: boolean; + // 全局属性名 + globalPropertyName?: string; +} + +// 创建WebSocket实例的函数 +export function createWebSocket(config: WebSocketConfig) { + // 响应式数据 + const socket = ref(null); + const isConnected = ref(false); + const isConnecting = ref(false); + const reconnectCount = ref(0); + const connectionStatus = ref(ConnectionStatus.DISCONNECTED); + const messages = ref([]); + + // 计算属性 + const statusClass = computed(() => { + switch (connectionStatus.value) { + case ConnectionStatus.CONNECTED: return 'status-connected'; + case ConnectionStatus.CONNECTING: return 'status-connecting'; + default: return 'status-disconnected'; + } + }); + + // 方法 + const connect = () => { + if (isConnected.value || isConnecting.value) return; + + isConnecting.value = true; + connectionStatus.value = ConnectionStatus.CONNECTING; + addSystemMessage('正在连接...'); + + try { + socket.value = new WebSocket( + config.url, + config.protocols ? config.protocols.split(',') : undefined + ); + + socket.value.onopen = onOpen; + socket.value.onmessage = onMessage; + socket.value.onerror = onError; + socket.value.onclose = onClose; + } catch (error) { + onError(error as Event); + } + }; + + const disconnect = () => { + if (socket.value) { + socket.value.close(); + socket.value = null; + } + isConnected.value = false; + isConnecting.value = false; + connectionStatus.value = ConnectionStatus.DISCONNECTED; + reconnectCount.value = 0; + addSystemMessage('连接已关闭'); + }; + + const reconnect = () => { + if (reconnectCount.value < config.reconnectAttempts) { + reconnectCount.value++; + addSystemMessage(`尝试重新连接 (${reconnectCount.value}/${config.reconnectAttempts})...`); + setTimeout(() => connect(), config.reconnectDelay); + } else { + addSystemMessage('已达到最大重连次数,连接终止'); + } + }; + + const sendMessage = (content: string) => { + if (socket.value && isConnected.value && content) { + socket.value.send(content); + addMessage(content, MessageType.OUTGOING); + } + }; + + const clearMessages = () => { + messages.value = []; + }; + + const addMessage = (content: string, type: MessageType) => { + messages.value.push({ + content, + type, + timestamp: new Date() + }); + }; + + const addSystemMessage = (content: string) => { + addMessage(content, MessageType.SYSTEM); + }; + + // WebSocket事件处理 + const onOpen = (e: Event) => { + isConnected.value = true; + isConnecting.value = false; + connectionStatus.value = ConnectionStatus.CONNECTED; + reconnectCount.value = 0; + addSystemMessage('连接已建立'); + }; + + const onMessage = (event: MessageEvent) => { + addMessage(event.data, MessageType.INCOMING); + }; + + const onError = (error: Event) => { + isConnecting.value = false; + connectionStatus.value = ConnectionStatus.ERROR; + addSystemMessage(`错误: ${error.type}`); + + if (!isConnected.value) { + reconnect(); + } + }; + + const onClose = (event: CloseEvent) => { + isConnected.value = false; + isConnecting.value = false; + connectionStatus.value = ConnectionStatus.DISCONNECTED; + addSystemMessage(`连接关闭: ${event.code} ${event.reason || ''}`); + + if (event.code !== 1000) { + reconnect(); + } + }; + + // 自动连接(如果配置了) + if (config.autoConnect) { + connect(); + } + + return { + // 状态 + isConnected, + isConnecting, + connectionStatus, + messages, + statusClass, + + // 方法 + connect, + disconnect, + sendMessage, + clearMessages + }; +} + +// 插件安装函数 +const WebSocketPlugin: Plugin = { + install(app: App, options: WebSocketPluginOptions = {}) { + const { + globalConfig = {}, + injectGlobal = false, + globalPropertyName = '$websocket' + } = options; + + // 合并默认配置和全局配置 + const defaultConfig: WebSocketConfig = { + url: 'wss://echo.websocket.org', + protocols: '', + reconnectAttempts: 5, + reconnectDelay: 3000, + autoConnect: false, + ...globalConfig + }; + + // 创建WebSocket实例 + const websocketInstance = createWebSocket(defaultConfig); + + // 如果需要,注入全局实例 + if (injectGlobal) { + app.config.globalProperties[globalPropertyName] = websocketInstance; + } + + // 提供WebSocket实例,以便组件通过inject使用 + app.provide('websocket', websocketInstance); + + // 注册全局组件(如果需要) + // app.component('WebSocketComponent', WebSocketComponent); + } +}; + +export default WebSocketPlugin;