fix: 登录失败自动自检三个服务端口并展示 SDK 原始错误(B-58)

- IMService 记录 onConnectFailed 的 code/error(lastConnectError)
- SDK 未初始化成功时 login 直接抛错,不再无限等待
- 登录页失败提示下附自检结果:账号服务/消息接口/消息长连接 通不通
- 版本号 1.0.2+3
This commit is contained in:
KIMI
2026-08-15 15:12:20 +08:00
parent f94c747aa4
commit a8cb84f4c7
3 changed files with 56 additions and 7 deletions
+42 -2
View File
@@ -1,6 +1,8 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../config.dart';
import '../services/auth_api.dart';
import '../services/call_service.dart';
import '../services/im_service.dart';
@@ -92,14 +94,52 @@ class _LoginScreenState extends State<LoginScreen> {
MaterialPageRoute(builder: (_) => const HomeScreen()),
);
} on AuthException catch (e) {
setState(() => _error = e.message);
await _fail(e.message);
} catch (_) {
setState(() => _error = '登录出错了,请稍后再试');
await _fail('登录出错了,请稍后再试');
} finally {
if (mounted) setState(() => _logging = false);
}
}
/// 登录失败:在提示下方附上服务器自检结果,方便远程定位是哪一段不通
Future<void> _fail(String msg) async {
final parts = [msg];
try {
parts.add(await _diagnoseServer());
} catch (_) {
// 自检本身失败不影响原提示
}
final sdkErr = IMService.instance.lastConnectError;
if (sdkErr != null && sdkErr.isNotEmpty) parts.add('消息组件报告:$sdkErr');
if (mounted) setState(() => _error = parts.join('\n'));
}
/// 逐个探测三个服务端口:能拿到任何 HTTP 响应就算通
Future<String> _diagnoseServer() async {
final dio = Dio(BaseOptions(
connectTimeout: const Duration(seconds: 5),
receiveTimeout: const Duration(seconds: 5),
));
Future<String> probe(String label, String url) async {
try {
await dio.get(url);
return '$label通';
} on DioException catch (e) {
return e.response != null ? '$label通' : '$label不通';
} catch (_) {
return '$label不通';
}
}
final results = await Future.wait([
probe('账号服务', '$authApiBase/api/health'),
probe('消息接口', '$apiAddr/'),
probe('消息长连接', 'http://$serverHost:$wsPort/'),
]);
return '自检:${results.join('')}';
}
@override
Widget build(BuildContext context) {
return Scaffold(
+13 -4
View File
@@ -36,6 +36,9 @@ class IMService extends ChangeNotifier {
/// 与服务器的连接状态(断网横幅用)
ConnectStatus connectStatus = ConnectStatus.idle;
/// 最近一次连接失败的原始错误(诊断展示用)
String? lastConnectError;
/// 是否已登录
bool loggedIn = false;
@@ -108,12 +111,14 @@ class IMService extends ChangeNotifier {
connectStatus = ConnectStatus.connecting;
notifyListeners();
},
onConnectSuccess: () {
connectStatus = ConnectStatus.success;
notifyListeners();
},
onConnectFailed: (code, error) {
connectStatus = ConnectStatus.failed;
lastConnectError = '$code $error';
notifyListeners();
},
onConnectSuccess: () {
connectStatus = ConnectStatus.success;
lastConnectError = null;
notifyListeners();
},
onKickedOffline: _forceLogout,
@@ -191,6 +196,10 @@ class IMService extends ChangeNotifier {
/// 登录(init 之后调用)。userID/token 来自公司账号登录接口。
Future<void> login({required String userID, required String token}) async {
await init();
if (!sdkReady) {
// initSDK 返回 false:SDK 没初始化成功,直接登录会无限等待
throw StateError('消息组件初始化失败');
}
final user = await OpenIM.iMManager.login(
userID: userID,
token: token,
+1 -1
View File
@@ -1,7 +1,7 @@
name: changlian
description: 畅联 —— 公司内部通讯 App(手机端)
publish_to: "none"
version: 1.0.1+2
version: 1.0.2+3
environment:
sdk: ">=3.6.0 <4.0.0"