You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
maotu-webtopo/src/utils/STOMP_USAGE.md

6.6 KiB

STOMP 服务使用指南

简介

这是一个基于 @stomp/stompjs 库封装的 STOMP 服务,提供了完整的连接、订阅、发布和消息处理功能。

注意: 您的项目使用的是 STOMP over WebSocket 协议,而不是 MQTT。

主要功能

  • 自动连接和重连
  • 服务注册机制
  • 消息自动分发
  • TypeScript 类型支持
  • 错误处理和日志记录

使用方法

1. 在 main.ts 中初始化

import { stompService } from './utils/stompService';

// 应用启动时连接 STOMP
const app = createApp(App);

// 连接 STOMP 服务器
stompService.connect({
  // brokerUrl: 'ws://your-server:8080/stomp-endpoint', // 可选,默认使用当前域名
  // username: 'your-username', // 可选
  // password: 'your-password', // 可选
  reconnectDelay: 5000 // 重连间隔,默认 5000ms
});

app.mount('#app');

2. 注册服务

// 在您的组件或 store 中
import { stompService } from '@/utils/stompService';

// 注册您的服务
stompService.registerService('node', {
  // 当 STOMP 连接成功时会调用此方法
  mqttReady() {
    console.log('Node 服务已就绪');
  },

  // 处理 Node 初始化消息
  msgNodeInit(data: any) {
    console.log('收到 Node 初始化数据:', data);
  },

  // 处理 Node 更新消息
  msgNode(data: any) {
    console.log('收到 Node 更新:', data);
  },

  // 运行时的数据
  runtimes: {}
});

// 注册其他服务
stompService.registerService('channel', {
  online(cid: string, isOnline: boolean) {
    console.log(`通道 ${cid} 状态:`, isOnline);
  }
});

stompService.registerService('video', {
  initVideo(data: any) {
    console.log('初始化视频:', data);
  },
  playVideo(data: any) {
    console.log('播放视频:', data);
  }
});

3. 发送消息

import { stompService, MqttCmd } from '@/utils/stompService';

// 发送控制命令
stompService.send('/app/web/write', MqttCmd.Control, {
  nodeId: 'node-001',
  action: 'turnOn'
});

// 发送 Node 更新
stompService.send('/app/web/write', MqttCmd.Node, {
  node: {
    id: 'node-001',
    status: 'active'
  }
});

4. 订阅主题

import { stompService } from '@/utils/stompService';

// 订阅自定义主题
stompService.subscribe('/topic/custom', (message) => {
  console.log('收到自定义消息:', message);
});

// 取消订阅
stompService.unsubscribe('/topic/custom');

5. 在 Vue 组件中使用

<template>
  <div>
    <el-button @click="sendCommand">发送命令</el-button>
    <div>连接状态{{ isConnected ? '已连接' : '未连接' }}</div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { stompService, MqttCmd } from '@/utils/stompService';

const isConnected = ref(false);

// 注册服务
onMounted(() => {
  stompService.registerService('myComponent', {
    mqttReady() {
      console.log('组件服务已就绪');
      isConnected.value = true;
    },
    onConnectionLost() {
      isConnected.value = false;
    }
  });
});

// 发送命令
function sendCommand() {
  stompService.send('/app/web/write', MqttCmd.Control, {
    command: 'test'
  });
}

// 组件卸载时清理
onUnmounted(() => {
  // 如果需要,可以在这里断开连接
  // stompService.disconnect();
});
</script>

消息命令类型

export const MqttCmd = {
  Channel: 'channel', // 通道状态
  NodeInit: 'nodeInit', // Node 初始化
  Node: 'node', // Node 更新
  User: 'user', // 用户登录
  Control: 'control', // 控制命令
  VideoInit: 'videoInit', // 视频初始化
  VideoCtl: 'videoCtl', // 视频控制
  Lock: 'lock', // 锁控
  Alarm: 'alarm', // 告警
  Info: 'info', // 通知提示
  SocketDebugger: 'socketDebugger' // 调试
};

API 文档

stompService.connect(config?)

连接 STOMP 服务器

参数:

  • config?: StompServiceConfig - 连接配置
    • brokerUrl?: string - STOMP 服务器地址
    • username?: string - 用户名
    • password?: string - 密码
    • reconnectDelay?: number - 重连间隔(毫秒)

stompService.disconnect()

断开 STOMP 连接

stompService.send(destination, cmd, value)

发送消息

参数:

  • destination: string - STOMP 目标地址
  • cmd: string - 命令类型
  • value: any - 消息内容

stompService.subscribe(destination, callback?)

订阅主题

参数:

  • destination: string - 目标地址
  • callback?: (message: StompMessage) => void - 消息回调

stompService.unsubscribe(destination)

取消订阅

参数:

  • destination: string - 目标地址

stompService.registerService(name, service)

注册服务

参数:

  • name: string - 服务名称
  • service: any - 服务对象

stompService.getClientStatus()

获取客户端状态

返回: { connected: boolean; client: Client | null }

注意事项

  1. 连接时机: 建议在应用启动时main.ts连接 STOMP
  2. 服务注册: 在组件的 onMounted 生命周期注册服务
  3. 清理资源: 组件卸载时根据需要断开连接或取消订阅
  4. 错误处理: 服务已内置重连机制,无需手动处理
  5. 类型安全: 所有方法都有 TypeScript 类型支持

迁移指南

从旧的 ExtJS 版本迁移:

旧代码

Rec.mqtt.connect();
Rec.service.node = { ... };
Rec.mqtt.send(cmd, value);

新代码

import { stompService } from '@/utils/stompService';

stompService.connect();
stompService.registerService('node', { ... });
stompService.send('/app/web/write', cmd, value);

示例项目结构

src/
├── utils/
│   └── stompService.ts          # STOMP 服务
├── services/
│   ├── nodeService.ts          # Node 服务
│   ├── channelService.ts       # 通道服务
│   └── videoService.ts         # 视频服务
└── views/
    └── YourComponent.vue       # 使用 STOMP 的组件

故障排除

连接失败

  • 检查 STOMP 服务器地址是否正确
  • 检查 WebSocket 是否可用(某些浏览器需要 HTTPS
  • 查看浏览器控制台日志

消息未收到

  • 确认服务已注册
  • 检查主题订阅是否正确
  • 查看消息格式是否符合预期

重连问题

  • 检查 reconnectDelay 设置
  • 查看服务器是否在线
  • 检查认证信息是否正确

与 MQTT 的区别

STOMP 是一个简单的文本协议,基于 WebSocket

  • 使用 destination 而不是 topic
  • 使用 send/publish 发送消息
  • 使用 subscribe 订阅消息
  • 连接地址格式:ws://host/stomp-endpoint