two improves of live room danmu (#5)

* feat: use wss instead of tcp connect

* feat: fallback to next server when live room danmu server connect failed
This commit is contained in:
PuerNya
2024-11-19 18:44:25 +08:00
committed by GitHub
parent f3a95a2c3a
commit 1a89e17abd
2 changed files with 25 additions and 12 deletions

View File

@@ -142,12 +142,15 @@ class LiveRoomController extends GetxController {
if (v['status']) { if (v['status']) {
LiveDanmakuInfo info = v['data']; LiveDanmakuInfo info = v['data'];
// logger.d("info => $info"); // logger.d("info => $info");
List<String> servers = [];
for (final host in info.data.hostList) {
servers.add('wss://${host.host}:${host.wssPort}/sub');
}
msgStream = LiveMessageStream( msgStream = LiveMessageStream(
streamToken: info.data.token, streamToken: info.data.token,
roomId: roomId, roomId: roomId,
uid: GStorage.userInfo.get('userInfoCache')?.mid ?? 0, uid: GStorage.userInfo.get('userInfoCache')?.mid ?? 0,
host: info.data.hostList[0].host, servers: servers,
port: info.data.hostList[0].port,
); );
msgStream?.addEventListener((obj) { msgStream?.addEventListener((obj) {
if (obj['cmd'] == 'DANMU_MSG') { if (obj['cmd'] == 'DANMU_MSG') {

View File

@@ -4,6 +4,7 @@ import 'dart:typed_data';
import 'package:PiliPalaX/services/loggeer.dart'; import 'package:PiliPalaX/services/loggeer.dart';
import 'package:brotli/brotli.dart'; import 'package:brotli/brotli.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
class PackageHeader { class PackageHeader {
int totalSize; int totalSize;
@@ -150,16 +151,16 @@ class HeartbeatPackage extends AbstractPackage<dynamic> {
} }
class LiveMessageStream { class LiveMessageStream {
String streamToken, host; String streamToken;
int roomId, uid, port; int roomId, uid;
List<String> servers;
List<void Function(dynamic obj)> eventListeners = []; List<void Function(dynamic obj)> eventListeners = [];
LiveMessageStream( LiveMessageStream(
{required this.streamToken, {required this.streamToken,
required this.roomId, required this.roomId,
required this.uid, required this.uid,
required this.host, required this.servers});
required this.port}); late WebSocket socket;
late Socket socket;
bool heartBeat = true; bool heartBeat = true;
PiliLogger logger = getLogger(); PiliLogger logger = getLogger();
final String logTag = "LiveStreamService"; final String logTag = "LiveStreamService";
@@ -185,12 +186,20 @@ class LiveMessageStream {
final marshaledData = authPackage.marshal(); final marshaledData = authPackage.marshal();
logger.d(marshaledData); logger.d(marshaledData);
try { try {
socket = await Socket.connect(host, port); Future<WebSocket> getSocket() async {
logger.d('$logTag ===> TCP连接建立'); for (final server in servers) {
try {
return await WebSocket.connect(server);
} catch (e) {}
}
throw Exception("all servers connect failed");
}
socket = await getSocket();
// logger.d('$logTag ===> TCP连接建立');
socket.add(authPackage.marshal()); socket.add(authPackage.marshal());
logger.d('$logTag ===> 发送认证包'); // logger.d('$logTag ===> 发送认证包');
await for (var data in socket) { await for (var data in socket) {
PackageHeader? header = PackageHeader.fromBytesData(data); PackageHeader? header = PackageHeader.fromBytesData(data);
if (header != null) { if (header != null) {
@@ -222,7 +231,8 @@ class LiveMessageStream {
} }
socket.close(); socket.close();
} catch (e) { } catch (e) {
logger.i('$logTag ===> TCP连接失败: $e'); SmartDialog.showToast("弹幕地址链接失败");
// logger.i('$logTag ===> TCP连接失败: $e');
} }
} }