From 91ce5bb73b7efc0741a060eb75ddf61e19d2f5e6 Mon Sep 17 00:00:00 2001 From: Oschly Date: Sun, 17 May 2026 21:23:53 +0200 Subject: [PATCH] Finish peer discovery section --- Thesis/Chapters/3. Implementation.typ | 71 +++++++++++++++++++++++++++ Thesis/main.pdf | 4 +- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/Thesis/Chapters/3. Implementation.typ b/Thesis/Chapters/3. Implementation.typ index c4d42cb..20961cc 100644 --- a/Thesis/Chapters/3. Implementation.typ +++ b/Thesis/Chapters/3. Implementation.typ @@ -165,7 +165,78 @@ func session( } ``` +Przechodząc do implementacji klienta, całość jest reprezentowana przez obiekt `NoteEditingSessionClient`. Jego konstruktor przyjmuje tylko identyfikator użytkownika, który jest typem `MCPeerID`, a implementacja obejmuje również stworzenie instancji `MCSession` do wykorzystania w trakcie połączenia z serwerem oraz instancji `MCNearbyServiceAdvertiser`, która propaguje informacje o kliencie do wszystkich innych klientów w pobliżu. Do obu obiektów przypisujemy obiekt delegujący, który będzie właśnie utworzoną instancją `NoteEditingSessionClient`. Dla `MCNearbyServiceAdvertiser` obiekt delegującego musi implementować protokół `MCNearbyServiceAdvertiserDelegate`. + +```swift +init(peer: MCPeerID) { + ownPeer = peer + session = MCSession( + peer: peer, + securityIdentity: nil, + encryptionPreference: .required + ) + advertiser = MCNearbyServiceAdvertiser( + peer: peer, + discoveryInfo: [:], + serviceType: "peered" + ) + super.init() + advertiser.delegate = self + session.delegate = self +} +``` + +Instancja `NoteEditingSessionClient` jest tworzona już przy pierwszym uruchomieniu aplikacji. Po utworzeniu przez użytkownika przyjaznej nazwy, która będzie używana do identyfikacji, w tle wywoływana jest metoda `startBrowsingForNotes()`, która wywołuje `startAdvertisingPeer()` obiektu `advertiser`. Przed rozpoczęciem nasłuchiwania aplikacja wywołuje również `stopBrowsingForNotes()`, by zatrzymać nasłuchiwanie, jeśli wcześniej było ono rozpoczęte, oraz zatrzymuje działanie obiektu `MCSession`, by zamknąć ewentualnie istniejącą sesję edycji notatki. + +```swift +func startBrowsingForNotes() { + advertiser.startAdvertisingPeer() +} + +func stopBrowsingForNotes() { + advertiser.stopAdvertisingPeer() + session.disconnect() +} +``` + +Jedyna metoda wymagana przez protokół `MCNearbyServiceAdvertiserDelegate` nazywa się `adverties()` i w argumentach przyjmuje informację o otrzymanym zaproszeniu i metadanych jakie to zaproszenie zawierało. Aplikacja próbuje zdekodować migawkę notatki, a następnie konstruuje obiekt `NoteInvitation` i umieszcza go w tablicy `invitations`. Umieszczenie w tablicy trzeba wykonać na głównym wątku, ponieważ, analogicznie jak w wypadku implementacji `MCNearbyServiceBrowserDelegate`, nie mamy gwarancji na jakim wątku będzie wykonywała się ta metoda. + +```swift + + +func advertiser( + _ advertiser: MCNearbyServiceAdvertiser, + didReceiveInvitationFromPeer peerID: MCPeerID, + withContext context: Data?, + invitationHandler: @escaping (Bool, MCSession?) -> Void +) { + guard + let context, + let noteContent = try? JSONDecoder().decode(NoteInvitation.NoteContent.self, from: context) + else { return } + + DispatchQueue.main.async { + self.invitations.append( + .init( + invitatorID: peerID, + note: noteContent, + invitationHandler: { [weak self, invitationHandler] accepted in + guard let self else { return } + invitationHandler(accepted, self.session) + DispatchQueue.main.async { + self.invitations.removeAll { $0.id == peerID } + } + } + ) + ) + } +} +``` + == Transportowanie danych + + + == Algorytm rozwiązywania konfliktów == Środowisko developerskie i stack technologiczny == Implementacja logiki P2P diff --git a/Thesis/main.pdf b/Thesis/main.pdf index 0b3bb0d..47dee64 100644 --- a/Thesis/main.pdf +++ b/Thesis/main.pdf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1fb961bbee69c95c549a7249ab2e969e40ac97dd0f5da6cd92c61cd8f32da6f4 -size 348558 +oid sha256:ba4bf600ebca97141276160ada6e6333aed80b1264b6b4f25a78dc6e8e887d49 +size 370166