375 lines
10 KiB
JavaScript
375 lines
10 KiB
JavaScript
// WebSocket连接诊断工具
|
||
class WebSocketDiagnostic {
|
||
constructor() {
|
||
this.testResults = [];
|
||
}
|
||
|
||
// 🔥 ===== 全面诊断WebSocket连接问题 =====
|
||
|
||
async runFullDiagnostic() {
|
||
console.log('🔍 开始WebSocket连接全面诊断...');
|
||
this.testResults = [];
|
||
|
||
// 1. 检查基础环境
|
||
await this.checkEnvironment();
|
||
|
||
// 2. 检查认证信息
|
||
await this.checkAuthentication();
|
||
|
||
// 3. 测试网络连接
|
||
await this.testNetworkConnectivity();
|
||
|
||
// 4. 测试WebSocket连接
|
||
await this.testWebSocketConnection();
|
||
|
||
// 5. 生成诊断报告
|
||
this.generateReport();
|
||
|
||
return this.testResults;
|
||
}
|
||
|
||
// 检查基础环境
|
||
async checkEnvironment() {
|
||
console.log('📱 检查小程序环境...');
|
||
|
||
try {
|
||
// 使用新的API替代已弃用的wx.getSystemInfoSync
|
||
const deviceInfo = wx.getDeviceInfo();
|
||
const appBaseInfo = wx.getAppBaseInfo();
|
||
const accountInfo = wx.getAccountInfoSync();
|
||
|
||
const envInfo = {
|
||
platform: deviceInfo.platform,
|
||
version: appBaseInfo.version,
|
||
SDKVersion: appBaseInfo.SDKVersion,
|
||
appId: accountInfo.miniProgram.appId,
|
||
envVersion: accountInfo.miniProgram.envVersion
|
||
};
|
||
|
||
console.log('📱 环境信息:', envInfo);
|
||
|
||
this.testResults.push({
|
||
test: '环境检查',
|
||
status: 'success',
|
||
data: envInfo
|
||
});
|
||
|
||
} catch (error) {
|
||
console.error('❌ 环境检查失败:', error);
|
||
this.testResults.push({
|
||
test: '环境检查',
|
||
status: 'error',
|
||
error: error.message
|
||
});
|
||
}
|
||
}
|
||
|
||
// 检查认证信息
|
||
async checkAuthentication() {
|
||
console.log('🔑 检查认证信息...');
|
||
|
||
try {
|
||
// 获取token
|
||
const userInfo = wx.getStorageSync('userInfo');
|
||
const directToken = wx.getStorageSync('token');
|
||
const app = getApp();
|
||
const appToken = app?.globalData?.userInfo?.token;
|
||
|
||
const authInfo = {
|
||
hasUserInfo: !!userInfo,
|
||
hasUserInfoToken: !!(userInfo?.token),
|
||
hasDirectToken: !!directToken,
|
||
hasAppToken: !!appToken,
|
||
userInfoTokenLength: userInfo?.token?.length || 0,
|
||
directTokenLength: directToken?.length || 0,
|
||
appTokenLength: appToken?.length || 0
|
||
};
|
||
|
||
console.log('🔑 认证信息:', authInfo);
|
||
|
||
// 检查token格式
|
||
const token = userInfo?.token || directToken || appToken;
|
||
if (token) {
|
||
authInfo.tokenPrefix = token.substring(0, 20) + '...';
|
||
authInfo.isJWT = token.startsWith('eyJ');
|
||
authInfo.tokenParts = token.split('.').length;
|
||
}
|
||
|
||
this.testResults.push({
|
||
test: '认证检查',
|
||
status: token ? 'success' : 'error',
|
||
data: authInfo,
|
||
error: token ? null : '未找到有效的认证token'
|
||
});
|
||
|
||
} catch (error) {
|
||
console.error('❌ 认证检查失败:', error);
|
||
this.testResults.push({
|
||
test: '认证检查',
|
||
status: 'error',
|
||
error: error.message
|
||
});
|
||
}
|
||
}
|
||
|
||
// 测试网络连接
|
||
async testNetworkConnectivity() {
|
||
console.log('🌐 测试网络连接...');
|
||
|
||
try {
|
||
// 检查网络状态
|
||
const networkInfo = await this.getNetworkType();
|
||
console.log('🌐 网络状态:', networkInfo);
|
||
|
||
// 测试HTTP连接
|
||
const httpTest = await this.testHttpConnection();
|
||
|
||
this.testResults.push({
|
||
test: '网络连接',
|
||
status: 'success',
|
||
data: {
|
||
network: networkInfo,
|
||
httpTest: httpTest
|
||
}
|
||
});
|
||
|
||
} catch (error) {
|
||
console.error('❌ 网络连接测试失败:', error);
|
||
this.testResults.push({
|
||
test: '网络连接',
|
||
status: 'error',
|
||
error: error.message
|
||
});
|
||
}
|
||
}
|
||
|
||
// 测试WebSocket连接
|
||
async testWebSocketConnection() {
|
||
console.log('🔌 测试WebSocket连接...');
|
||
|
||
const testUrls = [
|
||
'wss://api.faxianwo.me/api/v1/ws',
|
||
'wss://api.faxianwo.me',
|
||
'wss://api.faxianwo.me/ws'
|
||
];
|
||
|
||
const results = [];
|
||
|
||
for (const url of testUrls) {
|
||
console.log(`🔗 测试URL: ${url}`);
|
||
|
||
try {
|
||
const result = await this.testSingleWebSocketUrl(url);
|
||
results.push({
|
||
url: url,
|
||
status: result.success ? 'success' : 'error',
|
||
...result
|
||
});
|
||
} catch (error) {
|
||
results.push({
|
||
url: url,
|
||
status: 'error',
|
||
error: error.message
|
||
});
|
||
}
|
||
}
|
||
|
||
this.testResults.push({
|
||
test: 'WebSocket连接',
|
||
status: results.some(r => r.status === 'success') ? 'success' : 'error',
|
||
data: results
|
||
});
|
||
}
|
||
|
||
// 测试单个WebSocket URL
|
||
testSingleWebSocketUrl(url) {
|
||
return new Promise((resolve) => {
|
||
const startTime = Date.now();
|
||
let resolved = false;
|
||
|
||
const timeout = setTimeout(() => {
|
||
if (!resolved) {
|
||
resolved = true;
|
||
resolve({
|
||
success: false,
|
||
error: '连接超时',
|
||
duration: Date.now() - startTime
|
||
});
|
||
}
|
||
}, 10000);
|
||
|
||
try {
|
||
// 获取token
|
||
const userInfo = wx.getStorageSync('userInfo');
|
||
const token = userInfo?.token;
|
||
|
||
const testWs = wx.connectSocket({
|
||
url: `${url}?device_id=diagnostic_${Date.now()}`,
|
||
header: token ? {
|
||
'Authorization': `Bearer ${token}`
|
||
} : {},
|
||
timeout: 8000
|
||
});
|
||
|
||
testWs.onOpen((res) => {
|
||
if (!resolved) {
|
||
resolved = true;
|
||
clearTimeout(timeout);
|
||
testWs.close();
|
||
resolve({
|
||
success: true,
|
||
duration: Date.now() - startTime,
|
||
response: res
|
||
});
|
||
}
|
||
});
|
||
|
||
testWs.onError((error) => {
|
||
if (!resolved) {
|
||
resolved = true;
|
||
clearTimeout(timeout);
|
||
resolve({
|
||
success: false,
|
||
error: error.errMsg || 'WebSocket连接错误',
|
||
duration: Date.now() - startTime,
|
||
errorDetail: error
|
||
});
|
||
}
|
||
});
|
||
|
||
testWs.onClose((res) => {
|
||
if (!resolved) {
|
||
resolved = true;
|
||
clearTimeout(timeout);
|
||
resolve({
|
||
success: false,
|
||
error: '连接被关闭',
|
||
duration: Date.now() - startTime,
|
||
closeDetail: res
|
||
});
|
||
}
|
||
});
|
||
|
||
} catch (error) {
|
||
if (!resolved) {
|
||
resolved = true;
|
||
clearTimeout(timeout);
|
||
resolve({
|
||
success: false,
|
||
error: error.message,
|
||
duration: Date.now() - startTime
|
||
});
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
// 获取网络类型
|
||
getNetworkType() {
|
||
return new Promise((resolve, reject) => {
|
||
wx.getNetworkType({
|
||
success: resolve,
|
||
fail: reject
|
||
});
|
||
});
|
||
}
|
||
|
||
// 测试HTTP连接
|
||
testHttpConnection() {
|
||
return new Promise((resolve) => {
|
||
wx.request({
|
||
url: 'https://api.faxianwo.me/api/v1/health',
|
||
method: 'GET',
|
||
timeout: 5000,
|
||
success: (res) => {
|
||
resolve({
|
||
success: true,
|
||
statusCode: res.statusCode,
|
||
data: res.data
|
||
});
|
||
},
|
||
fail: (error) => {
|
||
resolve({
|
||
success: false,
|
||
error: error.errMsg
|
||
});
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// 生成诊断报告
|
||
generateReport() {
|
||
console.log('📋 生成诊断报告...');
|
||
console.log('='.repeat(50));
|
||
console.log('🔍 WebSocket连接诊断报告');
|
||
console.log('='.repeat(50));
|
||
|
||
this.testResults.forEach((result, index) => {
|
||
const status = result.status === 'success' ? '✅' : '❌';
|
||
console.log(`${index + 1}. ${status} ${result.test}`);
|
||
|
||
if (result.status === 'error') {
|
||
console.log(` 错误: ${result.error}`);
|
||
}
|
||
|
||
if (result.data) {
|
||
console.log(` 数据:`, result.data);
|
||
|
||
// 🔥 特别显示WebSocket连接的详细结果
|
||
if (result.test === 'WebSocket连接' && Array.isArray(result.data)) {
|
||
result.data.forEach((wsResult, i) => {
|
||
const wsStatus = wsResult.status === 'success' ? '✅' : '❌';
|
||
console.log(` ${wsStatus} ${wsResult.url}`);
|
||
if (wsResult.status === 'success') {
|
||
console.log(` 连接时间: ${wsResult.duration}ms`);
|
||
} else {
|
||
console.log(` 错误: ${wsResult.error}`);
|
||
if (wsResult.errorDetail) {
|
||
console.log(` 详情:`, wsResult.errorDetail);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
console.log('');
|
||
});
|
||
|
||
// 生成建议
|
||
this.generateSuggestions();
|
||
}
|
||
|
||
// 生成修复建议
|
||
generateSuggestions() {
|
||
console.log('💡 修复建议:');
|
||
|
||
const authResult = this.testResults.find(r => r.test === '认证检查');
|
||
const wsResult = this.testResults.find(r => r.test === 'WebSocket连接');
|
||
|
||
if (authResult?.status === 'error') {
|
||
console.log('1. 🔑 认证问题:请确保用户已正确登录并保存了token');
|
||
}
|
||
|
||
if (wsResult?.status === 'error') {
|
||
const wsData = wsResult.data || [];
|
||
const hasUrlError = wsData.some(r => r.error && r.error.includes('url not in domain list'));
|
||
|
||
if (hasUrlError) {
|
||
console.log('2. 🌐 域名配置问题:请在微信公众平台配置WebSocket合法域名');
|
||
console.log(' - 登录 mp.weixin.qq.com');
|
||
console.log(' - 开发 -> 开发管理 -> 开发设置');
|
||
console.log(' - 添加 wss://api.faxianwo.me 到WebSocket合法域名');
|
||
} else {
|
||
console.log('2. 🔌 WebSocket连接问题:请检查网络环境和后端服务状态');
|
||
}
|
||
}
|
||
|
||
console.log('='.repeat(50));
|
||
}
|
||
}
|
||
|
||
// 创建全局单例
|
||
const wsdiagnostic = new WebSocketDiagnostic();
|
||
|
||
module.exports = wsdiagnostic;
|