Couchbase Lite 2.8 release announced support for out-of-the-box, enterprise-grade peer-to-peer database sync solution. The new capability allows direct sync between Couchbase Lite enabled mobile and/or non-mobile embedded apps without the need for a cloud-based control point.
In this post, we provide an overview of the feature and we will demonstrate how easy it setup peer-to-peer sync between two clients. For more details, refer to the documentation pages for platform-specific API and sample code snippets.
First, some use cases …
Use Cases
App users in disconnected environments requiring the ability to collaborate with each other are candidates for peer-to-peer database sync. Here are a few such examples –
- Field Apps :
Field workers at a construction site, volunteers at disaster recovery zone, miners, health care workers at mobile clinics can collaborate and coordinate tasks with each other over a local area network without any internet connectivity. - Travel :
Flight attendants taking meal order updates can update inventory information that is automatically synced to other attendants in-flight. That way, a flight attendant does not offer a meal after the last one has been offered. - Hospitality :
Meal ordering workflows in restaurants can be automated. Servers can take and send orders to the kitchen, check on order status, take payments, etc. from mobile devices without leaving the side of the customer’s table. - Maritime :
Crew members aboard ships/vessel can record and sync equipment metrics in real time with other crew members, allowing to make real time decisions
Typical Deployment
Shown below is a typical deployment using Couchbase for peer-to-peer database sync in disconnected environments. A disconnected environment or the “edge” can operate autonomously without any connectivity to the backend cloud based servers. However, when there is internet connectivity, the changes from the disconnected edge can be synced with the remote Couchbase server through the Sync Gateway.
The Couchbase Lite clients can be organized in different topologies. It could be a star topology where one client can be designated as the primary control point or listener and the other clients can communicate with each other through the designated listener. Alternatively, clients can be organized in a connected mesh topology where every client is connected directly to every other client in the same network.
Peer-to-Peer workflow
Peer-to-peer sync is Websockets based and works over IP-based networks. It is the same protocol that is used to sync with the remote Sync Gateway. Here is a high level workflow of peer-to-peer data sync with Couchbase Lite. Every participating peer takes the role of a “Passive Peer” which is analogous to a server in a typical client-server communication and/or an “Active Peer” which is analogous to a client in a typical client-server communication. An app can take on role of both an active and passive peer.
- The websockets listener is initialized on the Passive Peer with the Couchbase Lite database to be synched. There are a number of configurable options available including the ability to specify port, network interface, TLSIdentity etc.
- One of the configurable options on the
Listener
is the authenticator callback function to be invoked when the listener receives credentials from the active peer. ThisListenerAuthenticator
callback function must be implemented by the app and includes logic to authenticate the client credentials. - The Passive peer advertises it’s services. This step is handled entirely within the app and Couchbase Lite does not play a role here. Typically, apps would leverage platform specific party frameworks such as NSNetService for this purpose. In fact, depending on the deployment, this step may be optional. For instance, the device could be configured with a static IP Address or if there is DNS support, then the client could be listening on a well-known URL.
- The active peer or client browses for passive peers to connect to. Again, this step is handled entirely within the app and Couchbase Lite does not play a role here. Typically, apps would leverage platform specific party frameworks such as NSNetService for this purpose. Of course, if the
Listener
is listening on a well-known address, then this step would be optional. - Once the active peer identifies the peer to connect to, it needs to establish a replication connection to the other endpoint. The replicator for peer-to-peer sync is configured exactly the same way as would be the case if it were establishing the connection to remote Sync Gateway.
- As part of the TLS handshake of the connection establishment, the server certs are authenticated. This happens transparently to the app.
- Once server cert is authenticated, the client credentials are sent to the listener for authentication. Couchbase Lite supports both basic authentication and client cert based authentication.
- The incoming credentials are sent to the registered
ListenerAuthenticator
where they are validated. Once authenticated, the communication channel is established between the peers. - Thereafter, everytime there is a document change in the database, the data change is automatically synced over to the other end. The direction of data transfer is configurable to be one-way or bidirectional.
Attributes of the Sync Technology
Doing sync correctly is difficult. There are several considerations and here is a cheat sheet of how peer-to-peer sync stacks up. Refer to the documentation for details
Feature | Couchbase Lite Peer-to-Peer Sync |
---|---|
Security | Out-of-box support for TLS encryption. Cert-based authentication. Basic Auth. Apps have to write 0 lines of code to get TLS encryption |
Network Resiliency | Retries with exponential back off. Continuous replications retry indefinitely while one-shot replications give up after certain number of attempts |
Efficiency | Using Delta Sync technlogy, optimize data transfer costs by only syncing parts of document that have changed |
Data Conflicts | Built-in. By default, conflicts are automatically resolved using predefined policies. In addition, Apps have flexibilty to specify own custom 2-way merge functions to deal with conflicts |
Developer Ease of Use | It takes just a few lines of code to get peer-to-peer sync going. Of course, there are a number of configurable options to customize it per your needs |
Multi-platform Support | Couchbase Lite is supported on a number of mobile and non-mobile platforms. The peer-to-peer data sync functionality enables sync between heterogenous platforms – for instance between an Android and iOS app |
Flexible Topologies | Since every participating peer can act as either a Listener or Replicator or both, Couchbase Lite clients participating in peer-to-peer sync can be organized in different topologies such as star, mesh etc. The choice depends on the needs of the app |
Getting Started Code
You can check out our tutorials pages for a complete app demonstrating the peer-to-peer sync capabiities. But here, I’d like to hare the minimal code required to get sync going so you can see for yourself how easy it is to get the previously described workflow going. Although the snippets are for iOS, it should be straightforward to map it to any other Couchbase Lite platform.
Passive Peer
The following code snippet initializes the listener on the Passive Peer that listens for incoming peer connections
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 |
// 1: Initialize Listener Configuration with the Couchbase Lite database to be synced let listenerConfig = URLEndpointListenerConfiguration(database: db) // 2: Attach authenticator to be used to validate client credentials. // In this sample, I have attached an authenticator for validating basic auth credentials listenerConfig.authenticator = ListenerPasswordAuthenticator.init { (username, password) -> Bool in if (self._allowlistedUsers.contains(["password" : password, "name":username])) { return true } return false } // Optionally, override other config options such as delta sync, TLSIdentity of the server etc. // By default, the listener is configured with a self signed cert that is generated by Couchbase LIte // This cert is referred to as "anonymous self signed cert" // 3: Initialize Listener with the Listener Configuration _websocketListener = URLEndpointListener(config: listenerConfig) // 4: Start the Listener. The listener is now listening for incoming connections try? websocketListener.start() |
Active Peer
The following code snippet initializes the replicator for secure peer-to-peer sync. It’s the same replicator logic used when replicating to remote endpoint
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// 1: Initialize Replicator Configuration with the Couchbase Lite database to be synced // and the URL endpoint corresponding to the websockets listener let config = ReplicatorConfiguration.init(database: userDb, target: URLEndpoint.init(url:targetUrl)) // 2: Set up authenticator with client credentials. In this case, we are using basic auth let authenticator = BasicAuthenticator(username: user, password: password) config.authenticator = authenticator // Optionally, set other config options such as replication mode, conflict resolver etc // 3: Initialize replicator with the replicator configuration replicatorForUserDb = Replicator.init(config: config) // 4: Set up replicator to only accept self signed certificate for server/listener // This is because we are using the default TLSIdentity on listener side which corresponds to // anonymous self signed cert config.acceptOnlySelfSignedServerCertificate = true // 5: Start the replication replicatorForUserDb?.start() |
That’s it! In just a few simple steps, you can get secure peer-to-peer sync going with Couchbase Lite
What about Peer-to-Peer Sync in 2.1 ?
If you have been working with Couchbase Lite, you are probably familiar with the peer-to-peer sync functionality that was introduced in 2.1 release of Couchbase Lite. In the 2.1 release, we provided an MessageEndpointConnection interface definition that had to be implemented by the app. Couchbase Lite replicator communicated with the app through this interface, providing the data changes that had to be synced. How to data got transferred to the receiving peer was completely upto the app. Providing an interface offered the flexibility for app developers to use any communications framework of choice and could be used across any transport (IP or non-IP).
In 2.8 we have vastly simplified the task by providing an out-of-box implementation for peer-to-peer sync over IP networks. As you’ll see shortly, it just takes a few lines of code to get going. The MessageEndpointConnection interface continues to remain supported. So if you have already implemented your sync solution with what was offered in 2.1, you are not required to migrate your solution to use the new API. In fact, that still remains your only option if you are syncing over non-IP based networks. However, if you are syncing over IP networks, it would be encouraged as it would greatly simplify your app code and reduce testing and maintenance costs.
What Next
Couchbase is the only peer-to-peer database sync solution that allows clients to directly communicate with each other in disconnected environments.
You can download Couchbase Lite and evauate the functionality for free.
If you want to dive into the details, here’s where you can find more information
– Documentation: Peer-to-Peer
– Tutorials: Peer-to-Peer
– Solutions Page: Peer-to-Peer Solutions
– Connect Video with Demo: Peer-to-Peer Sync using Couchbase Lite
The Couchbase Forums is a great place to reach out with questions. Please leave a comment below or feel free to reach out to me via Twitter or email me
I’m assuming that couchbase has given up on peer-to-peer mobile syncing on a Android platform. I have looked at the documentation and have not been able to get it to work. The only demo examples are with Ios and Xamarin. Not sure if it is so simple to implement why a simple demo example of bi-directional communication should be simple to provide for the Android community. I’m about ready to give up on couchbase.