客服端长连接
客服端基于MQTT协议实现长连接,用于与服务器建立持久的连接,支持实时消息收发。
协议说明
MQTT (Message Queuing Telemetry Transport) 是一种轻量级的发布/订阅消息传输协议,适用于实时通信场景。微语使用 MQTT 协议实现客服端与服务器之间的长连接通信,支持实时消息收发。
使用场景说明
MQTT长连接主要用于客服端向访客端发送消息的场景。当客服人员需要主动向网站访客或用户发送消息时,通过MQTT协议可以实现:
- 实时消息推送:客服消息可以立即推送到访客端
- 双向通信:支持客服和访客之间的实时对话
- 离线消息处理:访客离线时,消息会在其重 新连接后推送
- 多媒体消息支持:支持文本、图片、文件、语音等多种消息类型
典型流程:
- 客服端建立MQTT连接到服务器(通常在用户登录时建立)
- 客服端通过系统发送消息到服务器
- 服务器通过MQTT将消息推送到访客端
- 访客端实时接收并显示消息
快速开始
1. 安装依赖
npm install mqtt
2. 建立连接
import mqtt from 'mqtt';
// 全局MQTT客户端变量
let mqttClient = null;
// 连接参数类型定义
type mqttConnectOptions = {
uid: string; // 用户唯一标识符
username: string; // 用户名,用于MQTT认证
accessToken: string; // 访问令牌,作为MQTT密码进行认证
};
// 连接参数示例
const connectOptions: mqttConnectOptions = {
uid: 'user123', // 必填:用户ID,用于生成唯一的客户端ID
username: 'your_username', // 必填:用户名,通常是用户登录名
accessToken: 'your_access_token' // 必填:访问令牌,从服务端获取的JWT或其他认证令牌
};
// 建立 MQTT 连接
const mqttConnect = ({ uid, username, accessToken }) => {
// 检查访问令牌 - 匿名用户不建立MQTT连接
if (!accessToken) {
console.log("accessToken is empty, don't connect mqtt");
return;
}
// 生成唯一的客户端ID
// 格式:用户ID/渠道/设备ID
const deviceUid = 'device_unique_id'; // 设备唯一标识
const clientId = `${uid}/web/${deviceUid}`;
// MQTT连接配置详解
const options = {
keepalive: 30, // 心跳间隔(秒),设置0为禁用
clientId: clientId, // 客户端唯一标识,用于服务端识别 客户端身份
username: username, // MQTT用户名,用于服务端认证
password: accessToken, // MQTT密码(访问令牌),用于服务端认证
clean: false, // 持久会话:false=离线时可接收QoS 1和2消息
path: "/websocket", // WebSocket路径,WSS协议必需
reconnectPeriod: 5000, // 重连间隔(毫秒),设置0禁用自动重连
connectTimeout: 30000, // 连接超时(毫秒)
reschedulePings: true, // 发送数据包后重新安排ping消息
rejectUnauthorized: false, // WSS连接时是否验证服务器证书
};
// 连接 MQTT 服务器,并将客户端实例赋值给全局变量
mqttClient = mqtt.connect(getMqttUrl(), options);
return mqttClient;
};
MQTT服务器连接说明
微语支持两种WebSocket协议连接MQTT服务器:
// 1. 开发环境 - 使用 ws:// 协议(非加密连接)
const MQTT_URL_DEV = "ws://127.0.0.1:9885/websocket";
// 2. 生产环境 - 使用 wss:// 协议(加密连接)
const MQTT_URL_PROD = "wss://api.weiyuai.cn/websocket";
// 根据环境选择连接地址
const getMqttUrl = () => {
const isDevelopment = process.env.NODE_ENV === 'development';
return isDevelopment ? MQTT_URL_DEV : MQTT_URL_PROD;
};
// 使用示例
const client = mqtt.connect(getMqttUrl(), options);
协议说明:
-
ws:// - WebSocket协议,明文传输,适用于本地开发环境
- 优点:配置简单,调试方便
- 缺点:数据未加密,不安全
- 使用场景:本地开发、测试环境
-
wss:// - WebSocket Secure协议,TLS/SSL加密传输,适用于生产环境
- 优点:数据加密安全,防止中间人攻击
- 缺点:需要SSL证书配置
- 使用场景:生产环境、公网部署
连接地址格式:
协议://域名:端口/路径
ws://127.0.0.1:9885/websocket # 本地开发
wss://api.weiyuai.cn/websocket # 生产环境
3. 添加事件监听
// 连接成功事件
mqttClient.on('connect', () => {
console.log('MQTT 连接成功');
// 可以在这里订阅主题
});
// 接收消息事件
mqttClient.on('message', (topic, message, packet) => {
console.log('收到消息:', {
topic: topic,
message: message.toString(),
packet: packet
});
// 处理收到的消息
handleReceivedMessage(topic, message);
});
// 重连事件
mqttClient.on('reconnect', () => {
console.log('MQTT 重新连接中...');
});
// 连接关闭事件
mqttClient.on('close', () => {
console.log('MQTT 连接已关闭');
});
// 错误事件
mqttClient.on('error', (error) => {
console.error('MQTT 连接错误:', error);
});
// 离线事件
mqttClient.on('offline', () => {
console.log('MQTT 客户端离线');
});
核心功能
发送消息
微语支持两种消息发送方式:MQTT长连接发送(首选)和 HTTP REST API发送(降级)。系统会自动根据连接状态选择最佳发送方式。
消息格式标准
所有消息都采用统一的数据结构,支持多种消息类型:
// 标准消息结构
const messageStructure = {
uid: 'message_unique_id', // 消息唯一标识
type: 'MESSAGE_TYPE', // 消息类型(见下方类型列表)
content: 'message_content', // 消息内容(文本或JSON字符串)
timestamp: 1691234567890, // 消息时间戳
status: 'SENDING', // 消息状态:SENDING/SUCCESS/FAILED
channel: 'web', // 发送渠道:web/mobile/api
user: { // 发送者信息
uid: 'user123',
nickname: '用户昵称',
avatar: 'avatar_url',
type: 'USER' // 用户类型:USER/AGENT
},
thread: { // 会话信息
uid: 'thread_uid',
type: 'THREAD_TYPE',
topic: 'thread_topic'
},
extra: { // 扩展信息
orgUid: 'organization_id' // 组织ID
}
};
支持的消息类型
// 基础消息类型
const MESSAGE_TYPES = {
// 基础消息
TEXT: 'TEXT', // 文本消息
IMAGE: 'IMAGE', // 图片消息
FILE: 'FILE', // 文件消息
VIDEO: 'VIDEO', // 视频消息
AUDIO: 'AUDIO', // 音频消息
VOICE: 'VOICE', // 语音消息
LOCATION: 'LOCATION', // 位置消息
.....
};