复用官方 OpenIMLive 信令与房间,换票改走账号服务 /api/rtc_token;入口仅音频,占线/超时/重复回调与销毁释放由公司层防护。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
62 lines
1.9 KiB
Dart
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('发起通话失败,请稍后再试');
|
|
}
|
|
}
|
|
}
|