Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Couchbase Mobile 103: Building a Peer-to-Peer App with Couchbase Mobile: Couchbase Connect 2015

5,533 views

Published on

With Couchbase Lite, you can do peer-to-peer sync between two or more devices. Bring your laptops and code along with Jens and Pasin who will show you how to build a peer-to-peer mobile photo-sharing app, step-by-step, from scratch. You’ll see how the core code for sending and receiving photos is barely 100 lines of code and contains zero code directly involved in network communication.

Published in: Technology

Couchbase Mobile 103: Building a Peer-to-Peer App with Couchbase Mobile: Couchbase Connect 2015

  1. 1. BUILDING A PEER-TO-PEER APP WITH COUCHBASE MOBILE Jens Alfke, Pasin Suriyentrakorn Couchbase, Inc.
  2. 2. ©2015 Couchbase Inc. ‹#› Session Overview What is peer-to-peer? P2P with Couchbase Mobile’s replication architecture Implementing peer-to-peer Using Bonjour (aka mDNS, Network Service Discovery…) Direct pairing via QR-code scanning Demos
  3. 3. Peer-to-Peer Overview
  4. 4. ©2015 Couchbase Inc. ‹#› What Is Peer-To-Peer? Direct communication between clients No server required No Internet connection required
  5. 5. ©2015 Couchbase Inc. ‹#› Benefits Of Peer-To-Peer Developer doesn’t need to run servers End-user privacy Unmetered high bandwidth connections Useable with no Internet infrastructure Cellular “dead zones” Wilderness Disaster areas
  6. 6. ©2015 Couchbase Inc. ‹#› Drawbacks Of Peer-To-Peer Less reliable Hard to securely identify users or authenticate content Difficult to scale up On a LAN: Bandwidth growth Beyond a LAN: Connectivity and peer discovery
  7. 7. ©2015 Couchbase Inc. ‹#› Hybrid Approaches “A server is just a well-connected peer” Clients can connect to local peers and to a server
  8. 8. Peer-to-Peer With Couchbase Mobile
  9. 9. ©2015 Couchbase Inc. ‹#› Couchbase Mobile Replication Based on CouchDB* architecture Designed from the start for arbitrary topologies *Not the same as Couchbase Server’s XDCR Replicator REST API Active Passive
  10. 10. ©2015 Couchbase Inc. ‹#› Star Topology
  11. 11. ©2015 Couchbase Inc. ‹#› Cluster Topology “Cluster Of Unreliable Cheap Hardware”
  12. 12. ©2015 Couchbase Inc. ‹#› P2P Mesh Topology
  13. 13. ©2015 Couchbase Inc. ‹#› Replicating Documents & Revisions doc1 3-a9ff doc1 2-c31b B: “What’s new since last we spoke?” A: “I added rev #3-a9ff of doc1.” B: “That’s new to me!” A: “I’ll send it over…” A B
  14. 14. ©2015 Couchbase Inc. ‹#› P2P Mesh Topology
  15. 15. ©2015 Couchbase Inc. ‹#› The Problem With Naïve Meshes O(n2) connections is bad! Real mesh networks limit connections: Spanning trees Gossip protocols
  16. 16. Implementing Peer-to-Peer Part 1: Allowing Connections
  17. 17. ©2015 Couchbase Inc. ‹#› Allowing Peer Connections Link Couchbase Lite Listener component into app Start listener Congratulations! You are now a replication “server” Datastore CBL API App ReplicatorCBL API App Datastore REST API
  18. 18. ©2015 Couchbase Inc. ‹#› Allowing Peer Connections listener = CBLListener(manager: database.manager, port: 55555) listener.readOnly = true For Security: Prevents peers from pushing Docs to you! Or port 0, to allow the OS to choose a random open port. but a fixed port # is more optimal for the peer’s replicator!
  19. 19. Implementing Peer-to-Peer Part 2: Automatic Peer Discovery
  20. 20. ©2015 Couchbase Inc. ‹#› Automatic Peer Discovery “Who’s running this service/app [on this LAN]?” Advertise your own service: Type Name Address + port Small metadata (timestamp…) Browse for same service type Notified as peers go on/offline
  21. 21. ©2015 Couchbase Inc. ‹#› Multicast DNS (mDNS), DNS Service Discovery (DNS-SD) aka Bonjour™, ZeroConf, Avahi, Network Service Discovery RFC 6762, RFC 6763 iOS, Mac OS X, Android (4.1+), Linux Windows apps can integrate Apple’s mDNSResponder developer.apple.com/library/mac/documentation/Networkin g/Conceptual/NSNetServiceProgGuide developer.android.com/training/connect-devices-wirelessly
  22. 22. ©2015 Couchbase Inc. ‹#› Advertising Your Service listener = CBLListener(manager: database.manager, port: 55555) listener.readOnly = true listener.setBonjourName(userNickname, type: "_myapp._tcp") Note: setBonjourName isn’t available in CBL on Android yet. Instead, use NsdServiceInfo directly! Service name might be altered (number appended) to disambiguate it.
  23. 23. ©2015 Couchbase Inc. ‹#› Browsing For Peers (iOS) browser = NSNetServiceBrowser.new() browser.includesPeerToPeer = true browser.delegate = self browser.searchForServicesOfType("_myapp._tcp", inDomain: "local.") public func netServiceBrowser(sender: NSNetServiceBrowser, didFindService service: NSNetService, moreComing: Bool) { // … } public func netServiceBrowser(sender: NSNetServiceBrowser, didRemoveService service: NSNetService, moreComing: Bool) { // … }
  24. 24. ©2015 Couchbase Inc. ‹#› Connecting To A Peer (iOS) // Start async resolve, to find service’s hostname: service.delegate = self service.resolveWithTimeout(5.0) // NSNetService delegate callback: public func netServiceDidResolveAddress(service: NSNetService) { // Construct the remote DB URL: var components = NSURLComponents() components.scheme = "http" // Or "https" if peer uses SSL components.host = service.hostName! components.port = service.port components.path = "/" + remoteDatabaseName let url = components.URL! // Start replication: pull = localDB.createPullReplication(url)! pull.start() }
  25. 25. ©2015 Couchbase Inc. ‹#› Using Bonjour To Replicate Advertise a UUID as part of your service name Publish my db.latestSequence in service metadata Remember UUID, latestSequence of each ‘paired’ peer When peer’s latestSequence changes, start a pull replication
  26. 26. DEMO I: PeerSync App
  27. 27. Q: What’s Wrong With That Demo? A: No authentication!
  28. 28. ©2015 Couchbase Inc. ‹#› C Forging Documents or Revisions docByA B A B is sending me ‘docByA’ … but how do I know it was really created by A? 😒 😇 😴
  29. 29. ©2015 Couchbase Inc. ‹#› P2P Authentication Is A Hard Problem With no server accounts, how do you prove who you are? With no server to trust, how do you know whether data is valid?
  30. 30. ©2015 Couchbase Inc. ‹#› This Is Not A Typical Auth Problem SSL doesn’t help! HTTP authentication (A⇒B or B⇒C) doesn’t help! Only authenticating the data helps
  31. 31. ©2015 Couchbase Inc. ‹#› Digital Signatures Every user or device generates a key-pair Every revision is signed by the party who created it To validate a revision: Make sure the signature is valid Look up the author’s public key Compare signing key with author’s key
  32. 32. ©2015 Couchbase Inc. ‹#› Key Distribution Traditional Style: Trusted authority (server?) signs key into a certificate Server distributes certificate P2P Style: Device uses raw key or self-signed certificate Users ‘pair’ devices in person, trading keys over a secure channel
  33. 33. Implementing Peer-to-Peer Part 3: Manual 1::1 Pairing Pasin Suriyentrakorn
  34. 34. ©2015 Couchbase Inc. ‹#› PhotoDrop Receiver – Presenting the QR Code and Receiving Photos Sender – Selecting Photos Sender – Scanning a QR Code and Sending Photos
  35. 35. ©2015 Couchbase Inc. ‹#› Implementation Uses a QR code for peer discovery Uses one-time push replication to transfer photos Uses digest authentication Generates one-time user credentials Supports multiple platforms (e.g., iOS and Android)
  36. 36. ©2015 Couchbase Inc. ‹#› Storyboard ViewController SendViewController ReceiveViewController QR Code Scanner Presents a QR code
  37. 37. ©2015 Couchbase Inc. ‹#› ReceiveViewController Step 1: Start a listener listener = CBLListener(manager: CBLManager.sharedInstance(), port: 0) listener.requiresAuth = true let username = secureGenerateKey(NSCharacterSet.URLUserAllowedCharacterSet()) let password = secureGenerateKey(NSCharacterSet.URLPasswordAllowedCharacterSet()) listener.setPasswords([username : password]) var success = listener.start(&error) if (success) { syncUrl = genearteSyncURL(listener.URL, username: username, password: password, dbName: database.name) startObserveDatabaseChange() }
  38. 38. ©2015 Couchbase Inc. ‹#› ReceiveViewController Step 2: Observe database changes func startObserveDatabaseChange() { NSNotificationCenter.defaultCenter().addObserverForName( kCBLDatabaseChangeNotification, object: database, queue: nil) { (notification) -> Void in if let changes = notification.userInfo!["changes"] as? [CBLDatabaseChange] { for change in changes { dispatch_async(dispatch_get_main_queue(), { self.saveImageFromDocument(change.documentID) }) } } } }
  39. 39. ©2015 Couchbase Inc. ‹#› ReceiveViewController Step 3: Generate and display a QR code http://user:password@<listener host>:<port>/db Uses the iOS Core Image filter
  40. 40. ©2015 Couchbase Inc. ‹#› SendViewController Step 1: Scan a QR code Uses the iOS class AVCaptureSession with the output type AVMetadataObjectTypeQRCode
  41. 41. ©2015 Couchbase Inc. ‹#› ReceiveViewController Step 2: Create documents var docIds: [String] = [] for asset in sharedAssets! { //... var data = NSData(bytesNoCopy: imageBytes, length: buffered, freeWhenDone: true) let doc = database.createDocument() let rev = doc.newRevision() rev.setAttachmentNamed("photo", withContentType: "application/octet-stream", content: data) let saved = rev.save(&error) if saved != nil { docIds.append(doc.documentID) } }
  42. 42. ©2015 Couchbase Inc. ‹#› ReceiveViewController Step 3: Replicate documents replicator = database.createPushReplication(url) replicator.documentIDs = docIds NSNotificationCenter.defaultCenter().addObserverForName(kCBLReplicationChangeNotification, object: replicator, queue: nil) { (notification) -> Void in if self.replicator.lastError == nil { var totalCount = self.replicator.changesCount var completedCount = self.replicator.completedChangesCount if completedCount > 0 && completedCount == totalCount { self.statusLabel.text = "Sending Completed” } } else { self.statusLabel.text = "Sending Abort" } } replicator.start()
  43. 43. ©2015 Couchbase Inc. ‹#› Source Code https://github.com/couchbaselabs/photo-drop
  44. 44. Demo 2 PhotoDrop App
  45. 45. The End — Any Questions?

×