你想知道在 `onSocketOpen` 事件中发送数据时,如何控制发送频率,避免因发送过快导致服务器压力过大或小程序触发限流机制。
### 避免发送频率过高的解决方案
在 `onSocketOpen` 中控制发送频率,核心思路是通过**节流(Throttle)**、**防抖(Debounce)**或**消息队列**来限制发送速率。以下是几种具体实现方法:
#### 1. 节流(Throttle):固定时间间隔发送
限制在指定时间内只能发送一次数据,即使触发多次发送请求也只执行一次。
```javascript
// 定义节流函数
function throttle(func, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
lastTime = now;
func.apply(this, args);
}
};
}
// 建立WebSocket连接
wx.connectSocket({
url: 'wss://your-server.com/ws'
});
// 定义带节流的发送函数(每500ms最多发送一次)
const throttledSend = throttle(function(data) {
wx.sendSocketMessage({
data: JSON.stringify(data),
fail: (err) => console.error('发送失败:', err)
});
}, 500);
// 在onSocketOpen中使用节流函数
wx.onSocketOpen(() => {
console.log('连接已打开');
// 模拟高频发送场景
for (let i = 0; i < 10; i++) {
throttledSend({ type: 'data', value: i });
}
});
```
#### 2. 消息队列:按顺序间隔发送
将待发送的消息存入队列,通过定时器按固定间隔逐个发送,确保发送速率可控。
```javascript
Page({
data: {
messageQueue: [], // 消息队列
isSending: false // 是否正在发送中
},
onLoad() {
this.connectWebSocket();
},
connectWebSocket() {
wx.connectSocket({
url: 'wss://your-server.com/ws'
});
wx.onSocketOpen(() => {
console.log('连接已打开');
// 启动队列处理
this.processQueue();
});
},
// 添加消息到队列
addToQueue(data) {
this.data.messageQueue.push(data);
// 如果当前没有在发送,则启动处理
if (!this.data.isSending) {
this.processQueue();
}
},
// 处理消息队列(每300ms发送一条)
processQueue() {
if (this.data.messageQueue.length === 0) {
this.data.isSending = false;
return;
}
this.data.isSending = true;
const data = this.data.messageQueue.shift(); // 取出队首消息
wx.sendSocketMessage({
data: JSON.stringify(data),
success: () => {
console.log('发送成功:', data);
// 延迟后处理下一条
setTimeout(() => this.processQueue(), 300);
},
fail: (err) => {
console.error('发送失败:', err);
// 失败时重新放入队列尾部
this.data.messageQueue.push(data);
setTimeout(() => this.processQueue(), 1000); // 失败后延迟更长时间重试
}
});
},
// 在onSocketOpen后调用(示例)
sendDataAfterOpen() {
// 批量添加消息到队列
this.addToQueue({ type: 'init', content: '初始化数据' });
this.addToQueue({ type: 'user_info', id: '123' });
this.addToQueue({ type: 'history', limit: 10 });
}
});
```
#### 3. 单次初始化数据发送:确保只发送一次
如果只是在连接成功时发送初始化数据,避免重复发送,可通过状态标记控制。
```javascript
let hasSentInitData = false; // 标记是否已发送初始化数据
wx.connectSocket({
url: 'wss://your-server.com/ws'
});
wx.onSocketOpen(() => {
console.log('连接已打开');
// 确保初始化数据只发送一次
if (!hasSentInitData) {
wx.sendSocketMessage({
data: JSON.stringify({ type: 'init', timestamp: Date.now() }),
success: () => {
hasSentInitData = true; // 发送成功后标记
console.log('初始化数据发送成功');
}
});
}
});
```
### 关键注意事项
- **节流 vs 防抖**:节流用于固定频率发送(如每500ms一次),防抖用于延迟合并发送(如停止操作后500ms发送最后一次)。
- **队列优先级**:可扩展队列实现优先级机制,重要消息优先发送。
- **错误重试**:发送失败时应将消息重新入队并延迟重试,避免消息丢失。
- **小程序限制**:微信小程序对WebSocket发送频率有隐式限制,建议单次连接后每秒发送不超过5-10条消息。
### 总结
1. 使用**节流函数**可限制固定时间内的发送次数,适合高频触发场景。
2. 使用**消息队列**可严格控制发送间隔,确保消息按顺序、匀速发送。
3. 使用**状态标记**可避免初始化数据重复发送,保证关键数据只发送一次。
根据你的具体业务场景选择合适的控制方式,既能保证数据及时发送,又能避免频率过高带来的问题。