Files
tongxunruanjian/mobile-next/lib/company/rtc/rtc_token_api.dart
T
3832e080c4 feat(mobile-next): 迁移 Android 一对一语音通话薄适配与入口
复用官方 OpenIMLive 信令与房间,换票改走账号服务 /api/rtc_token;入口仅音频,占线/超时/重复回调与销毁释放由公司层防护。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 07:58:24 +08:00

62 lines
1.9 KiB
Dart

import 'package:dio/dio.dart';
import 'package:openim_common/openim_common.dart';
import '../auth/auth_api.dart';
import '../config/app_endpoints.dart';
import 'livekit_call_config.dart';
import 'rtc_token_mapper.dart';
/// 公司账号服务换 LiveKit 进房 token。不改官方 SDK 核心,也不改现网接口。
class RtcTokenApi {
RtcTokenApi({Dio? dio})
: _dio = dio ??
Dio(BaseOptions(
baseUrl: AppEndpoints.authApiBase,
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 10),
));
final Dio _dio;
Future<SignalingCertificate> getToken({
required String room,
required String identity,
required String authToken,
}) async {
if (room.isEmpty || identity.isEmpty) {
throw AuthException('通话数据不完整');
}
if (authToken.isEmpty) {
throw AuthException('登录状态已失效,请重新登录');
}
try {
final resp = await _dio.post(
LiveKitCallConfig.rtcTokenPath,
data: {'room': room, 'identity': identity},
options: Options(headers: {'Authorization': 'Bearer $authToken'}),
);
final cred = RtcTokenMapper.parse(
resp.data,
fallbackLiveUrl: AppEndpoints.livekitUrl,
);
return SignalingCertificate(
token: cred.token,
roomID: room,
liveURL: cred.liveURL,
);
} on DioException catch (e) {
final data = e.response?.data;
if (data is Map && data['msg'] != null && data['msg'].toString().isNotEmpty) {
throw AuthException(data['msg'].toString());
}
throw AuthException('连不上语音服务,请检查网络', network: true);
} on AuthException {
rethrow;
} on FormatException catch (e) {
throw AuthException(e.message);
} catch (_) {
throw AuthException('发起通话失败,请稍后再试');
}
}
}