jellyflood/Shared/ServerDiscovery/ServerDiscovery.swift

61 lines
1.7 KiB
Swift

//
// Swiftfin is subject to the terms of the Mozilla Public
// License, v2.0. If a copy of the MPL was not distributed with this
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2024 Jellyfin & Jellyfin Contributors
//
import Combine
import Factory
import Foundation
import UDPBroadcast
class ServerDiscovery {
@Injected(LogManager.service)
private var logger
private var connection: UDPBroadcastConnection?
init() {
connection = try? UDPBroadcastConnection(
port: 7359,
handler: handleServerResponse,
errorHandler: handleError
)
}
var discoveredServers: AnyPublisher<ServerResponse, Never> {
discoveredServersPublisher
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
private var discoveredServersPublisher = PassthroughSubject<ServerResponse, Never>()
func broadcast() {
try? connection?.sendBroadcast("Who is JellyfinServer?")
}
func close() {
connection?.closeConnection()
discoveredServersPublisher.send(completion: .finished)
}
private func handleServerResponse(_ ipAddress: String, _ port: Int, data: Data) {
do {
let response = try JSONDecoder().decode(ServerResponse.self, from: data)
discoveredServersPublisher.send(response)
logger.debug("Found local server: \"\(response.name)\" at: \(response.url.absoluteString)")
} catch {
logger.debug("Unable to decode local server response from: \(ipAddress):\(port)")
}
}
private func handleError(_ error: UDPBroadcastConnection.ConnectionError) {
logger.debug("Error handling response: \(error.localizedDescription)")
}
}