You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
12 KiB
323 lines
12 KiB
// 全面测试客服在线状态问题
|
|
console.log('=== 全面测试客服在线状态问题 ===\n');
|
|
|
|
const WebSocket = require('ws');
|
|
const http = require('http');
|
|
|
|
// 配置参数
|
|
const TEST_MANAGER_ID = '22'; // 我们测试的客服ID
|
|
const API_BASE_URL = 'http://localhost:3003';
|
|
const API_ENDPOINT = '/api/managers';
|
|
const WS_URL = 'ws://localhost:3003';
|
|
|
|
// 全局变量存储连接期间的API检查结果
|
|
let connectionManagerStatus = null;
|
|
let duringManager = null; // 用于存储连接期间的API检查结果,供测试分析使用
|
|
|
|
// 步骤1: 先检查API返回的客服列表,看看我们的测试客服是否存在
|
|
async function checkApiResponse() {
|
|
console.log('🔍 步骤1: 检查API返回的客服列表');
|
|
|
|
return new Promise((resolve, reject) => {
|
|
http.get(`${API_BASE_URL}${API_ENDPOINT}`, (res) => {
|
|
let data = '';
|
|
|
|
res.on('data', (chunk) => {
|
|
data += chunk;
|
|
});
|
|
|
|
res.on('end', () => {
|
|
try {
|
|
const result = JSON.parse(data);
|
|
console.log(`✅ API请求成功,状态码: ${res.statusCode}`);
|
|
console.log(`📋 客服列表长度: ${result.data ? result.data.length : 0}`);
|
|
|
|
// 查找我们测试的客服
|
|
if (result.data && result.data.length > 0) {
|
|
console.log('\n📝 客服列表详情:');
|
|
result.data.forEach((manager, index) => {
|
|
console.log(` ${index + 1}. ${manager.name} (id=${manager.id}, managerId=${manager.managerId}, online=${manager.online ? '✅ 在线' : '❌ 离线'})`);
|
|
});
|
|
|
|
// 特别检查我们的测试客服
|
|
const testManager = result.data.find(m =>
|
|
String(m.id) === TEST_MANAGER_ID || String(m.managerId) === TEST_MANAGER_ID
|
|
);
|
|
|
|
if (testManager) {
|
|
console.log(`\n🔍 找到测试客服记录:`);
|
|
console.log(` 姓名: ${testManager.name}`);
|
|
console.log(` id: ${testManager.id}`);
|
|
console.log(` managerId: ${testManager.managerId}`);
|
|
console.log(` 当前在线状态: ${testManager.online ? '✅ 在线' : '❌ 离线'}`);
|
|
resolve(testManager);
|
|
} else {
|
|
console.log(`\n❌ 未找到id或managerId为${TEST_MANAGER_ID}的客服记录`);
|
|
resolve(null);
|
|
}
|
|
} else {
|
|
console.log('❌ API返回的数据为空或格式错误');
|
|
resolve(null);
|
|
}
|
|
} catch (error) {
|
|
console.error('❌ 解析API响应失败:', error.message);
|
|
reject(error);
|
|
}
|
|
});
|
|
}).on('error', (error) => {
|
|
console.error(`❌ API请求失败: ${error.message}`);
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
|
|
// 步骤2: 建立WebSocket连接并进行客服认证
|
|
async function testWebSocketConnection() {
|
|
console.log('\n🔍 步骤2: 建立WebSocket连接并进行客服认证');
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const ws = new WebSocket(WS_URL);
|
|
let isAuthenticated = false;
|
|
let connectionTimer;
|
|
let apiCheckTimer;
|
|
|
|
ws.on('open', () => {
|
|
console.log('✅ WebSocket连接已建立');
|
|
|
|
// 发送认证消息
|
|
const authMessage = {
|
|
type: 'auth',
|
|
managerId: TEST_MANAGER_ID,
|
|
userType: 'manager' // 明确指定用户类型为客服
|
|
};
|
|
|
|
console.log(`📤 发送认证消息:`, authMessage);
|
|
ws.send(JSON.stringify(authMessage));
|
|
|
|
// 设置超时
|
|
connectionTimer = setTimeout(() => {
|
|
if (!isAuthenticated) {
|
|
console.error('❌ 认证超时');
|
|
ws.close();
|
|
reject(new Error('认证超时'));
|
|
}
|
|
}, 5000);
|
|
});
|
|
|
|
ws.on('message', (message) => {
|
|
try {
|
|
const data = JSON.parse(message.toString());
|
|
console.log('📥 收到服务器消息:', data);
|
|
|
|
if (data.type === 'auth_success') {
|
|
console.log('✅ 认证成功!');
|
|
isAuthenticated = true;
|
|
clearTimeout(connectionTimer);
|
|
|
|
// 发送心跳消息
|
|
setTimeout(() => {
|
|
console.log('📤 发送心跳消息');
|
|
ws.send(JSON.stringify({ type: 'ping' }));
|
|
|
|
// 保持连接5秒,给服务器足够时间更新状态
|
|
console.log('⏱️ 保持连接5秒,等待状态完全更新...');
|
|
|
|
// 在连接期间执行API检查(优化:在连接中直接进行检查,确保并发控制)
|
|
apiCheckTimer = setTimeout(async () => {
|
|
console.log('\n🔍 连接期间执行API检查...');
|
|
duringManager = await checkApiDuringConnection(); // 将结果保存到全局变量
|
|
console.log('✅ 连接期间API检查结果已保存,准备后续分析');
|
|
}, 2000); // 认证后2秒进行API检查
|
|
|
|
setTimeout(() => {
|
|
console.log('\n🔄 准备关闭连接');
|
|
ws.close();
|
|
}, 5000);
|
|
}, 1000);
|
|
} else if (data.type === 'pong') {
|
|
console.log('✅ 收到心跳响应');
|
|
}
|
|
} catch (error) {
|
|
console.error('❌ 解析WebSocket消息失败:', error.message);
|
|
}
|
|
});
|
|
|
|
ws.on('close', (code, reason) => {
|
|
console.log(`🔌 WebSocket连接已关闭,代码: ${code}, 原因: ${reason || '未知'}`);
|
|
clearTimeout(apiCheckTimer);
|
|
resolve(isAuthenticated);
|
|
});
|
|
|
|
ws.on('error', (error) => {
|
|
console.error('❌ WebSocket错误:', error.message);
|
|
clearTimeout(connectionTimer);
|
|
clearTimeout(apiCheckTimer);
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
|
|
// 步骤3: 检查连接期间的API响应(在WebSocket连接建立后但未关闭前)
|
|
async function checkApiDuringConnection() {
|
|
console.log('🔍 检查WebSocket连接期间的API响应(实时检查)');
|
|
// 不再需要额外等待,因为在WebSocket连接中已经控制了时机
|
|
|
|
return new Promise((resolve, reject) => {
|
|
http.get(`${API_BASE_URL}${API_ENDPOINT}`, (res) => {
|
|
let data = '';
|
|
|
|
res.on('data', (chunk) => {
|
|
data += chunk;
|
|
});
|
|
|
|
res.on('end', () => {
|
|
try {
|
|
const result = JSON.parse(data);
|
|
|
|
if (result.data && result.data.length > 0) {
|
|
// 查找我们测试的客服
|
|
const testManager = result.data.find(m =>
|
|
String(m.id) === TEST_MANAGER_ID || String(m.managerId) === TEST_MANAGER_ID
|
|
);
|
|
|
|
if (testManager) {
|
|
console.log(`\n🔍 连接期间客服状态:`);
|
|
console.log(` 姓名: ${testManager.name}`);
|
|
console.log(` 当前在线状态: ${testManager.online ? '✅ 在线' : '❌ 离线'}`);
|
|
resolve(testManager);
|
|
} else {
|
|
console.log(`❌ 未找到测试客服记录`);
|
|
resolve(null);
|
|
}
|
|
} else {
|
|
resolve(null);
|
|
}
|
|
} catch (error) {
|
|
console.error('❌ 解析API响应失败:', error.message);
|
|
resolve(null);
|
|
}
|
|
});
|
|
}).on('error', (error) => {
|
|
console.error(`❌ API请求失败: ${error.message}`);
|
|
resolve(null);
|
|
});
|
|
});
|
|
}
|
|
|
|
// 步骤4: 检查关闭连接后的API响应
|
|
async function checkApiAfterClose() {
|
|
console.log('\n🔍 步骤4: 检查关闭连接后的API响应');
|
|
await new Promise(resolve => setTimeout(resolve, 500)); // 等待状态更新
|
|
|
|
return new Promise((resolve, reject) => {
|
|
http.get(`${API_BASE_URL}${API_ENDPOINT}`, (res) => {
|
|
let data = '';
|
|
|
|
res.on('data', (chunk) => {
|
|
data += chunk;
|
|
});
|
|
|
|
res.on('end', () => {
|
|
try {
|
|
const result = JSON.parse(data);
|
|
|
|
if (result.data && result.data.length > 0) {
|
|
// 查找我们测试的客服
|
|
const testManager = result.data.find(m =>
|
|
String(m.id) === TEST_MANAGER_ID || String(m.managerId) === TEST_MANAGER_ID
|
|
);
|
|
|
|
if (testManager) {
|
|
console.log(`\n🔍 关闭连接后客服状态:`);
|
|
console.log(` 姓名: ${testManager.name}`);
|
|
console.log(` 当前在线状态: ${testManager.online ? '✅ 在线' : '❌ 离线'}`);
|
|
resolve(testManager);
|
|
} else {
|
|
console.log(`❌ 未找到测试客服记录`);
|
|
resolve(null);
|
|
}
|
|
} else {
|
|
resolve(null);
|
|
}
|
|
} catch (error) {
|
|
console.error('❌ 解析API响应失败:', error.message);
|
|
resolve(null);
|
|
}
|
|
});
|
|
}).on('error', (error) => {
|
|
console.error(`❌ API请求失败: ${error.message}`);
|
|
resolve(null);
|
|
});
|
|
});
|
|
}
|
|
|
|
// 运行测试
|
|
async function runTest() {
|
|
try {
|
|
console.log('=== 全面测试客服在线状态问题 ===\n');
|
|
console.log(`🎯 测试目标: managerId = ${TEST_MANAGER_ID}\n`);
|
|
|
|
// 步骤1: 检查初始状态
|
|
const beforeManager = await checkApiResponse();
|
|
|
|
if (!beforeManager) {
|
|
console.log('\n⚠️ 警告: 未找到测试客服记录,这可能是状态显示问题的原因');
|
|
return;
|
|
}
|
|
|
|
// 步骤2: 测试WebSocket认证
|
|
const authSuccess = await testWebSocketConnection();
|
|
|
|
if (!authSuccess) {
|
|
console.log('\n❌ 认证失败,无法测试在线状态更新');
|
|
return;
|
|
}
|
|
|
|
// 步骤3: 检查连接期间的状态(已在WebSocket连接中直接执行,这里不再单独调用)
|
|
console.log('\n📋 注意: 连接期间的API检查已在WebSocket连接中直接执行,以确保最佳并发控制');
|
|
// duringManager变量将在WebSocket连接中的API检查后通过全局变量更新
|
|
|
|
// 步骤4: 检查关闭连接后的状态
|
|
const afterManager = await checkApiAfterClose();
|
|
|
|
// 分析结果
|
|
console.log('\n=== 测试结果分析 ===');
|
|
console.log(`初始状态: ${beforeManager?.online ? '✅ 在线' : '❌ 离线'}`);
|
|
|
|
// 确保duringManager正确被更新
|
|
if (!duringManager) {
|
|
console.log('⚠️ 警告: 连接期间状态未正确更新,可能是时序问题');
|
|
}
|
|
|
|
console.log(`连接期间状态: ${duringManager?.online ? '✅ 在线' : '❌ 离线'}`);
|
|
console.log(`关闭后状态: ${afterManager?.online ? '✅ 在线' : '❌ 离线'}`);
|
|
|
|
// 放宽条件:只要在连接期间显示在线,就认为测试成功
|
|
if (duringManager?.online) {
|
|
console.log('\n✅ 成功! 客服在连接期间正确显示为在线状态。');
|
|
|
|
if (!beforeManager?.online && !afterManager?.online) {
|
|
console.log('🌟 完整流程验证成功: 初始离线 -> 连接期间在线 -> 关闭后离线');
|
|
} else {
|
|
console.log('⚠️ 注意: 初始或关闭后的状态可能有延迟,但连接期间状态正确。');
|
|
}
|
|
|
|
console.log('\n🎉 测试通过! 客服在线状态系统工作正常。');
|
|
} else {
|
|
console.log('\n❌ 失败! 即使WebSocket认证成功,客服在连接期间仍显示离线。');
|
|
|
|
console.log('\n📋 可能的问题原因:');
|
|
console.log(' 1. 服务器中使用的managerId格式与API中使用的不匹配(string vs number)');
|
|
console.log(' 2. onlineManagers Map的key与API查询时使用的key不一致');
|
|
console.log(' 3. 数据库和内存状态不同步');
|
|
console.log(' 4. 服务器认证逻辑有问题,没有正确将manager添加到onlineManagers');
|
|
console.log('\n💡 检查建议: 查看服务器日志中onlineManagers的内容和键类型');
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('\n❌ 测试执行失败:', error.message);
|
|
}
|
|
}
|
|
|
|
// 启动测试
|
|
runTest();
|
|
|