p2p-swift / Sources / IrdP2P / WebRTC / PeerConnectionFactory.swift
298 words
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import Foundation
import IrdP2PSignaling

public enum SDPType: String, Sendable { case offer, answer }

public enum PeerConnectionState: Sendable, Equatable { case new, connecting, connected, disconnected, failed, closed }

public enum SignalingState: Sendable, Equatable { case stable, haveLocalOffer, haveRemoteOffer, other, closed }

/// Value events from a peer connection, safe to hop between actors.
public enum PeerConnectionEvent: Sendable, Equatable {
    case iceCandidate(candidate: String, sdpMid: String?, sdpMLineIndex: Int?)
    case iceGatheringComplete
    case connectionState(PeerConnectionState)
    case dataChannelOpen
    case dataChannelClosed
    case message(Data, isBinary: Bool)
    case bufferedAmountLow
}

/// One WebRTC peer connection with a single negotiated, reliable, ordered data
/// channel (`id 0`, label `ird`) created on both sides up front.
public protocol PeerConnectionHandle: Sendable {
    var events: AsyncStream<PeerConnectionEvent> { get }
    /// Creates and applies a local offer; returns its SDP.
    func createOffer(iceRestart: Bool) async throws -> String
    /// Creates and applies a local answer to the current remote offer; returns its SDP.
    func createAnswer() async throws -> String
    func setRemoteDescription(_ type: SDPType, sdp: String) async throws
    /// Rolls back a pending local offer (perfect-negotiation glare handling).
    func rollback() async throws
    func addIceCandidate(candidate: String, sdpMid: String?, sdpMLineIndex: Int?) async throws
    func signalingState() async -> SignalingState
    func send(text: String) async throws
    func send(data: Data) async throws
    func bufferedAmount() async -> Int
    func close() async
}

/// Creates peer connections; the WebRTC-backed factory is the default, the in-memory
/// one pairs handles inside one process for tests.
public protocol PeerConnectionFactory: Sendable {
    func makePeerConnection(ice: IceConfiguration) async throws -> any PeerConnectionHandle
    /// What rooms call, passing `RoomOptions.continualGathering`. Factories that do not
    /// gather ICE candidates need not implement it: the default ignores the flag.
    func makePeerConnection(ice: IceConfiguration, continualGathering: Bool) async throws -> any PeerConnectionHandle
}

extension PeerConnectionFactory {
    public func makePeerConnection(ice: IceConfiguration, continualGathering: Bool) async throws -> any PeerConnectionHandle {
        try await makePeerConnection(ice: ice)
    }
}

static mirror of HEAD · about · clone: git clone https://ird.cod-sursa.ro/p2p-swift.git