mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-14 17:55:58 -07:00
Init repo
This commit is contained in:
commit
764b6034e3
566 changed files with 212335 additions and 0 deletions
114
lib/providers/discovery_provider.dart
Normal file
114
lib/providers/discovery_provider.dart
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||
import 'package:fladder/providers/service_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'discovery_provider.g.dart';
|
||||
part 'discovery_provider.mapper.dart';
|
||||
|
||||
@riverpod
|
||||
class ServerDiscovery extends _$ServerDiscovery {
|
||||
final String discoveryMessage = 'Who is JellyfinServer?';
|
||||
final int discoveryPort = 7359;
|
||||
final int maxServerCount = 25;
|
||||
final Duration timeOut = const Duration(seconds: 5);
|
||||
late final JellyService api = JellyService(ref, JellyfinOpenApi.create());
|
||||
|
||||
@override
|
||||
Stream<List<DiscoveryInfo>> build() async* {
|
||||
final List<DiscoveryInfo> discoveredServers = [];
|
||||
final StreamController<List<DiscoveryInfo>> controller = StreamController<List<DiscoveryInfo>>();
|
||||
|
||||
// Bind the socket and start listening
|
||||
final RawDatagramSocket socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0);
|
||||
socket.broadcastEnabled = true;
|
||||
|
||||
// Send the broadcast message
|
||||
socket.send(
|
||||
utf8.encode(discoveryMessage),
|
||||
InternetAddress('255.255.255.255'), // Broadcast address
|
||||
discoveryPort,
|
||||
);
|
||||
|
||||
// log('Discovery message sent. Waiting for response...');
|
||||
|
||||
// Set a timer to close the socket after the timeout
|
||||
Timer timer = Timer(timeOut, () {
|
||||
// log('Timeout reached, closing socket.');
|
||||
if (discoveredServers.isEmpty) {
|
||||
controller.add([]);
|
||||
}
|
||||
socket.close();
|
||||
controller.close(); // Close the stream controller when done
|
||||
});
|
||||
|
||||
socket.listen((RawSocketEvent event) {
|
||||
if (event == RawSocketEvent.read) {
|
||||
Datagram? dg = socket.receive();
|
||||
if (dg != null) {
|
||||
// Decode the response
|
||||
String response = utf8.decode(dg.data);
|
||||
Map<String, dynamic> jsonResponse = jsonDecode(response);
|
||||
|
||||
final discovery = DiscoveryInfo.fromMap(jsonResponse);
|
||||
|
||||
discoveredServers.add(discovery);
|
||||
controller.add(List<DiscoveryInfo>.from(discoveredServers)); // Emit the updated list
|
||||
|
||||
if (discoveredServers.length >= maxServerCount) {
|
||||
log('Max servers found, closing socket.');
|
||||
timer.cancel();
|
||||
socket.close();
|
||||
controller.close(); // Close the stream controller
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
yield* controller.stream;
|
||||
|
||||
// Handle disposal when the provider is no longer needed
|
||||
ref.onDispose(() {
|
||||
timer.cancel();
|
||||
socket.close();
|
||||
controller.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@MappableClass()
|
||||
class DiscoveryInfo with DiscoveryInfoMappable {
|
||||
@MappableField(key: 'Id')
|
||||
final String id;
|
||||
@MappableField(key: 'Name')
|
||||
final String name;
|
||||
@MappableField(key: 'Address')
|
||||
final String address;
|
||||
@MappableField(key: "EndpointAddress")
|
||||
final String? endPointAddress;
|
||||
|
||||
const DiscoveryInfo({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.address,
|
||||
required this.endPointAddress,
|
||||
});
|
||||
|
||||
factory DiscoveryInfo.fromMap(Map<String, dynamic> map) => DiscoveryInfoMapper.fromMap(map);
|
||||
factory DiscoveryInfo.fromJson(String json) => DiscoveryInfoMapper.fromJson(json);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is DiscoveryInfo && other.id == id && other.address == address;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode ^ address.hashCode;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue