npm拉下来最新的2.3.9版本,发现一些原来Js代码已经不能用了。顺便解读了下最新定义的内容
// <reference types="node" />
export const VERSIONS: {
V1_0: string;
V1_1: string;
V1_2: string;
supportedVersions: () => string[];
};
export class Client {
connected: boolean;
counter: number;
heartbeat: {
incoming: number;
outgoing: number;
};
maxWebSocketFrameSize: number;
subscriptions: {};
ws: WebSocket;
debug(...args: string[]): any;
connect(
headers: { login: string; passcode: string; host?: string | undefined }, // 头部
connectCallback: (frame?: Frame) => any, // 返回消息的监听器,从服务器收消息
errorCallback?: (error: Frame | string) => any, // 错误信息的监听器
): any;
connect(headers: {}, connectCallback: (frame?: Frame) => any, errorCallback?: (error: Frame | string) => any): any;
connect(
login: string,
passcode: string,
connectCallback: (frame?: Frame) => any,
errorCallback?: (error: Frame | string) => any,
host?: string,
): any;
disconnect(disconnectCallback: () => any, headers?: {}): any; // 拆连接
send(destination: string, headers?: {}, body?: string): any;
subscribe(destination: string, callback?: (message: Message) => any, headers?: {}): Subscription;
unsubscribe(id: string): void;
begin(transaction: string): any;
commit(transaction: string): any;
abort(transaction: string): any;
ack(messageID: string, subscription: string, headers?: {}): any;
nack(messageID: string, subscription: string, headers?: {}): any;
}
export interface Subscription {
id: string;
unsubscribe(): void;
}
export interface Message extends Frame {
ack(headers?: {}): any;
nack(headers?: {}): any;
}
export class Frame {
command: string;
headers: {};
body: string;
constructor(command: string, headers?: {}, body?: string);
toString(): string;
static sizeOfUTF8(s: string): number;
static unmarshall(datas: any): any;
static marshall(command: string, headers?: {}, body?: string): any;
}
export function client(url: string, protocols?: string | string[]): Client;
export function over(ws: WebSocket): Client;
export function overTCP(host: string, port: number): Client;
export function overWS(url: string): Client;
export function setInterval(interval: number, f: (...args: any[]) => void): NodeJS.Timer;
export function clearInterval(id: NodeJS.Timer): void;
ChatGPT
typescript
Copy code
/// <reference types="node" />
// 定义了支持的 STOMP 协议版本
export const VERSIONS: {
V1_0: string;
V1_1: string;
V1_2: string;
supportedVersions: () => string[];
};
// 定义了 STOMP 客户端类
export class Client {
connected: boolean; // 标识客户端是否连接
counter: number; // 消息计数器
heartbeat: { // 心跳配置
incoming: number; // 接收心跳频率
outgoing: number; // 发送心跳频率
};
maxWebSocketFrameSize: number; // WebSocket 最大消息帧大小
subscriptions: {}; // 订阅列表
ws: WebSocket; // WebSocket 连接
// 调试日志函数
debug(...args: string[]): any;
// 连接到 STOMP 服务器的方法,支持多种重载形式
connect(
headers: { login: string; passcode: string; host?: string | undefined }, // 连接头信息
connectCallback: (frame?: Frame) => any, // 连接成功的回调函数
errorCallback?: (error: Frame | string) => any, // 连接错误的回调函数
): any;
connect(headers: {}, connectCallback: (frame?: Frame) => any, errorCallback?: (error: Frame | string) => any): any;
connect(
login: string,
passcode: string,
connectCallback: (frame?: Frame) => any,
errorCallback?: (error: Frame | string) => any,
host?: string,
): any;
// 断开与 STOMP 服务器的连接
disconnect(disconnectCallback: () => any, headers?: {}): any;
// 发送消息到指定目的地
send(destination: string, headers?: {}, body?: string): any;
// 订阅指定目的地的消息
subscribe(destination: string, callback?: (message: Message) => any, headers?: {}): Subscription;
// 取消订阅
unsubscribe(id: string): void;
// 开启事务
begin(transaction: string): any;
// 提交事务
commit(transaction: string): any;
// 回滚事务
abort(transaction: string): any;
// 手动确认消息
ack(messageID: string, subscription: string, headers?: {}): any;
// 手动否认消息
nack(messageID: string, subscription: string, headers?: {}): any;
}
// 订阅对象接口
export interface Subscription {
id: string; // 订阅 ID
unsubscribe(): void; // 取消订阅方法
}
// 消息对象接口,扩展自 Frame
export interface Message extends Frame {
ack(headers?: {}): any; // 手动确认消息方法
nack(headers?: {}): any; // 手动否认消息方法
}
// STOMP 帧对象类
export class Frame {
command: string; // 帧命令
headers: {}; // 帧头部
body: string; // 帧主体
constructor(command: string, headers?: {}, body?: string); // 构造函数
// 将帧对象转换为字符串
toString(): string;
// 计算 UTF-8 编码字符串的大小
static sizeOfUTF8(s: string): number;
// 反序列化 STOMP 帧
static unmarshall(datas: any): any;
// 序列化 STOMP 帧
static marshall(command: string, headers?: {}, body?: string): any;
}
// 创建 STOMP 客户端的辅助函数
export function client(url: string, protocols?: string | string[]): Client;
// 使用现有的 WebSocket 连接创建 STOMP 客户端的辅助函数
export function over(ws: WebSocket): Client;
// 使用 TCP 连接创建 STOMP 客户端的辅助函数
export function overTCP(host: string, port: number): Client;
// 使用 WebSocket 连接地址创建 STOMP 客户端的辅助函数
export function overWS(url: string): Client;
// 发送客户端心跳
export function setInterval(interval: number, f: (...args: any[]) => void): NodeJS.Timer;
// 取消发送客户端心跳
export function clearInterval(id: NodeJS.Timer): void;
然后写一段简短的代码:
<script lang="ts" setup>
import { ref, inject, onMounted, onBeforeUnmount, defineProps, watch } from 'vue'
import Stomp from 'stompjs'
const MQTT_SERVICE = 'ws://localhost:15674/ws' // mq服务地址
const MQTT_USERNAME = 'user' // mq连接用户名
const MQTT_PASSWORD = '123456' // mq连接密码
function connectMQ() {
const socket = new WebSocket(MQTT_SERVICE)
const stompClient = Stomp.over(socket)
stompClient.heartbeat.outgoing = 0
stompClient.heartbeat.incoming = 0
const onConnected = () => {
console.log('登录成功!')
stompClient.subscribe('a11022a6-ad17-459e-8b23-1ca6599af4f9', onMessageReceived) // 订阅需要的队列
}
const onMessageReceived = (message: { body: any }) => {
console.log('返回数据:', message.body)
}
const onError = (error: any) => {
console.error('RabbitMQ连接失败,错误原因:', error)
console.error('5秒后重新连接......')
window.setTimeout(() => {
connectMQ()
}, 5000)
}
stompClient.connect(MQTT_USERNAME, MQTT_PASSWORD, onConnected, onError, '/')
}
onMounted(() => {
connectMQ()
})
</script>
然后去rabbitmq管理器给队列发个点对点消息:
试了下,能收到消息
但是出现一个问题,连接质量似乎不怎么好啊,老是掉线:
dashboard.vue:33 RabbitMQ连接失败,错误原因: Whoops! Lost connection to ws://localhost:15674/ws
看来连接质量不怎么好啊,加上个心跳,每15s跳一次:
前面代码关闭了下推,我们加上个上报看看,默认是10s一次,前面都设置为0了:
By default, stomp.js defines a heartbeat of 10000,10000
(to send and receive heartbeats every 10 seconds).
<script lang="ts" setup>
import { ref, inject, onMounted, onUnmounted, defineProps, watch } from 'vue'
import Stomp from 'stompjs'
const MQTT_SERVICE = 'ws://localhost:15674/ws' // mq服务地址
const MQTT_USERNAME = 'user' // mq连接用户名
const MQTT_PASSWORD = '123456' // mq连接密码
let heartbeat: NodeJS.Timer | undefined = undefined
function connectMQ() {
const socket = new WebSocket(MQTT_SERVICE)
const stompClient = Stomp.over(socket)
stompClient.heartbeat.outgoing = 15000
stompClient.heartbeat.incoming = 0
const onConnected = () => {
console.log('登录成功!')
stompClient.subscribe('a11022a6-ad17-459e-8b23-1ca6599af4f9', onMessageReceived)
}
const onMessageReceived = (message: { body: any }) => {
console.log('返回数据:', message.body)
}
const onError = (error: any) => {
console.error('RabbitMQ连接失败,错误原因:', error)
console.error('5秒后重新连接......')
window.setTimeout(() => {
connectMQ()
}, 5000)
}
stompClient.connect(MQTT_USERNAME, MQTT_PASSWORD, onConnected, onError, '/')
heartbeat = Stomp.setInterval(15000, () => {
console.log('心跳呀')
})
}
onMounted(() => {
connectMQ()
})
onUnmounted(() => {
if (heartbeat) {
Stomp.clearInterval(heartbeat)
}
})
</script>
这下稳定多了:
正式代码可以考虑把接收的消息数据和方法都放到vuex的store里