Skip to content

Commit f0259a2

Browse files
committed
DOC-13056 mobile simplification: p2p pages (#956)
* DOC-13056 mobile simplification: p2p pages I've verified with my human eyeballs that the output for Android pages matches the published output, in terms of structure / images rendering / etc. Simplification has the following known issues, due to the methodology (using antora assembler as if to generate a single PDF) * Some document titles are changed (because assembler uses the left-hand nav as the authoritative source) * Some headings are promoted This is actually a "correction" - e.g. the original doc may have had unsemantic headings, with a skipped level. Assembler normalises the output and rewrites headings based on nav level. Though we then remove the correction for nav level, we don't "uncorrect" the fix. * Paragraph IDs are namespaced to make them unique. This should be *fine* within a single document, as assembler should update both anchor and link. But deep links from another page may be broken. * Code samples are *inlined* rather than retained as an include:: I've tried to add a `// include::...` comment in the source so it's easy to fix this. In addition, you may want to request changes such as: * back off from inlining certain {page-...} attributes to retain genericity where actually needed. (Probably not here, mostly an issue for e.g. installation pages) * Any other demangling I missed. * added C docs, and reran based on DOC-13123 * cleanup improvements Demangled: * source include:: * :::links * [.column] * DOC-13056 iterate from comments by @simon-dew: * removed incorrect [#id] for dlists within [tabs] set (bug in antora-assembler) * make regex for demunging `:::` ids non-greedy * rename all pages in nav * DOC-13056 fix [[ex-repl-mon]] mangling --------- Co-authored-by: Simon Dew <[email protected]>
1 parent 4eab931 commit f0259a2

23 files changed

+13315
-140
lines changed

modules/android/pages/p2psync-custom.adoc

Lines changed: 342 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,352 @@
1+
12
= Integrate a Custom Built Listener
23
:page-aliases: learn/java-android-p2psync-custom.adoc
34
ifdef::show_edition[:page-edition: {release}] {enterprise}
4-
ifdef::prerelease[:page-status: {prerelease}]
55
:page-role:
66
:description: Couchbase Lite database peer-to-peer sync- integrate a custom built listener
77

88

9-
include::partial$_set_page_context_for_android.adoc[]
10-
// :param-name: {lang-name-android}
11-
// :param-title: {lang-title-android}
12-
// :param-module: {lang-mod-android}
13-
:topic-group: Using Peer-to-Peer Synchronization (custom)
14-
:param-related: {url-api-references}[API Reference] | {p2psync-websocket--xref} | {p2psync-custom--xref}
9+
:source-language: Java
10+
11+
12+
:source-language: Kotlin
13+
14+
15+
// :param-name: kotlin
16+
// :param-title: Android
17+
// :param-module: android
18+
19+
20+
[abstract]
21+
--
22+
Description -- _{description}_ +
23+
Related Content -- https://docs.couchbase.com/mobile/{major}.{minor}.{maintenance-android}{empty}/couchbase-lite-android/[API Reference] | xref:android:p2psync-websocket.adoc[Peer-to-Peer] | xref:android:p2psync-custom.adoc[Integrate Custom Listener]
24+
--
25+
26+
[#overview]
27+
== Overview
28+
29+
.Enterprise Edition only
30+
IMPORTANT: Peer-to-Peer Synchronization is an https://www.couchbase.com/products/editions[Enterprise Edition] feature.
31+
You must purchase the Enterprise License, which includes official https://www.couchbase.com/support-policy[Couchbase Support].
32+
To use it in production (also see the https://www.couchbase.com/licensing-and-support-faq[FAQ]).
33+
34+
This content covers how to integrate a custom __MessageEndpointListener__ solution with Couchbase Lite to handle the data transfer, which is the sending and receiving of data.
35+
Where applicable, we discuss how to integrate Couchbase Lite into the workflow.
36+
37+
The following sections describe a typical Peer-to-Peer workflow.
38+
39+
[#peer-discovery]
40+
== Peer Discovery
41+
42+
Peer discovery is the first step.
43+
The communication framework will generally include a Peer discovery API for devices to advertise themselves on the network and to browse for other Peers.
44+
45+
image::ROOT:discovery.png[]
46+
47+
[#active-peer]
48+
=== Active Peer
49+
50+
The first step is to initialize the Couchbase Lite database.
51+
52+
[#passive-peer]
53+
=== Passive Peer
54+
55+
In addition to initializing the database, the Passive Peer must initialize the `MessageEndpointListener`.
56+
The `MessageEndpointListener` acts as a Listener for incoming connections.
57+
58+
[source]
59+
----
60+
include::android:example$codesnippet_collection.kt[tag=listener,indent=0]
61+
----
62+
63+
[#peer-selection-and-connection-setup]
64+
== Peer Selection and Connection Setup
65+
66+
67+
Once a Peer device is found, the application code must decide whether it should establish a connection with that Peer.
68+
This step includes inviting a Peer to a session and Peer authentication.
69+
70+
This is handled by the Communication Framework.
71+
72+
image::ROOT:selection.png[]
73+
74+
Once the remote Peer has been authenticated, the next step is to connect with that Peer and initialize the Message Endpoint API.
75+
76+
77+
[#replication-setup]
78+
== Replication Setup
79+
80+
81+
image::ROOT:connection.png[]
82+
83+
[#active-peer-2]
84+
=== Active Peer
85+
86+
When the connection is established, the active Peer must instantiate a `MessageEndpoint` object corresponding to the remote Peer.
87+
88+
[source]
89+
----
90+
include::android:example$codesnippet_collection.kt[tag=message-endpoint,indent=0]
91+
----
92+
93+
The `MessageEndpoint` initializer takes the following arguments.
94+
95+
. `uid`: a unique ID that represents the remote active Peer.
96+
. `target`: This represents the remote passive Peer and could be any suitable representation of the remote Peer.
97+
It could be an Id, URL etc.
98+
If using the MultiPeerConnectivity Framework, this could be the MCPeerID.
99+
. `protocolType`: specifies the kind of transport you intend to implement.
100+
There are two options.
101+
** The default (`MessageStream`) means that you want to "send a series of messages", or in other words the Communication Framework will control the formatting of messages so that there are clear boundaries between messages.
102+
** The alternative (`ByteStream`) means that you just want to send raw bytes over the stream and Couchbase should format for you to ensure that messages get delivered in full.
103+
+
104+
Typically, the Communication Framework will handle message assembly and disassembly so you would use the `MessageType` option in most cases.
105+
106+
. `delegate`: the delegate that will implement the `MessageEndpointDelegate` protocol, which is a factory for `MessageEndpointConnection`.
107+
108+
Then, a `Replicator` is instantiated with the initialized `MessageEndpoint` as the target.
109+
110+
[source]
111+
----
112+
include::android:example$codesnippet_collection.kt[tag=message-endpoint-replicator,indent=0]
113+
----
114+
115+
Next, Couchbase Lite will call back the application code through the `MessageEndpointDelegate.createConnection` interface method.
116+
When the application receives the callback, it must create an instance of `MessageEndpointConnection` and return it.
117+
118+
119+
[source]
120+
----
121+
include::android:example$codesnippet_collection.kt[tag=create-connection,indent=0]
122+
----
123+
Next, Couchbase Lite will call back the application code through the `MessageEndpointConnection.open` method.
124+
125+
[source]
126+
----
127+
include::android:example$codesnippet_collection.kt[tag=active-peer-open,indent=0]
128+
----
129+
130+
The connection argument is then set on an instance variable.
131+
The application code must keep track of every `ReplicatorConnection` associated with every `MessageEndpointConnection`.
132+
133+
The `MessageError` argument in the completion block specifies whether the error is recoverable or not.
134+
If it is a recoverable error, the replicator will begin a retry process, creating a new `MessageEndpointConnection` instance.
135+
136+
[#passive-peer-2]
137+
=== Passive Peer
138+
139+
After connection establishment on the Passive Peer, the first step is to initialize a new `MessageEndpointConnection` and pass it to the listener.
140+
This message tells the listener to accept incoming data from that Peer.
141+
142+
[source]
143+
----
144+
include::android:example$codesnippet_collection.kt[tag=advertizer-accept,indent=0]
145+
----
146+
147+
`messageEndpointListener` is the instance of the `MessageEndpointListener` that was created in the first step (<<peer-discovery,Peer Discovery>>)
148+
149+
Couchbase Lite will call the application code back through the `MessageEndpointConnection.open` method.
150+
151+
[source]
152+
----
153+
include::android:example$codesnippet_collection.kt[tag=passive-peer-open,indent=0]
154+
----
155+
156+
The `connection` argument is then set on an instance variable.
157+
The application code must keep track of every `ReplicatorConnection` associated with every `MessageEndpointConnection`.
158+
159+
At this point, the connection is established, and both Peers are ready to exchange data.
160+
161+
162+
[#pushpull-replication]
163+
== Push/Pull Replication
164+
165+
Typically, an application needs to send data and receive data.
166+
The directionality of the replication could be any of the following.
167+
168+
* *Push only:* The data is pushed from the local database to the remote database.
169+
170+
* *Pull only:* The data is pulled from the remote database to the local database.
171+
172+
* *Push and Pull:* The data is exchanged both ways.
173+
174+
Usually, the remote is a Sync Gateway database identified through a URL.
175+
In Peer-to-Peer syncing, the remote is another Couchbase Lite database.
176+
177+
image::ROOT:replication.png[]
178+
179+
The replication lifecycle is handled through the `MessageEndpointConnection`.
180+
181+
[#active-peer-3]
182+
=== Active Peer
183+
184+
When Couchbase Lite calls back the application code through the `MessageEndpointConnection.send` method, you should send that data to the other Peer using the communication framework.
185+
186+
[source]
187+
----
188+
include::android:example$codesnippet_collection.kt[tag=active-peer-send,indent=0]
189+
----
190+
191+
Once the data is sent, call the completion block to acknowledge the completion.
192+
You can use the `MessageError` in the completion block to specify whether the error is recoverable.
193+
If it is a recoverable error, the replicator will begin a retry process, creating a new `MessageEndpointConnection`.
194+
195+
196+
When data is received from the passive Peer via the Communication Framework, you call the `ReplicatorConnection.receive` method.
197+
198+
[source]
199+
----
200+
include::android:example$codesnippet_collection.kt[tag=active-peer-receive,indent=0]
201+
----
202+
203+
The replication connection's `receive` method is called. Which then processes the data to persist to the local database.
204+
205+
[#passive-peer-3]
206+
=== Passive Peer
207+
208+
As in the case of the active Peer, the passive Peer must implement the `MessageEndpointConnection.send` method to send data to the other Peer.
209+
210+
[source]
211+
----
212+
include::android:example$codesnippet_collection.kt[tag=passive-peer-send,indent=0]
213+
----
214+
215+
Once the data is sent, call the completion block to acknowledge the completion.
216+
You can use the `MessageError` in the completion block to specify whether the error is recoverable.
217+
If it is a recoverable error, the replicator will begin a retry process, creating a new `MessageEndpointConnection`.
218+
219+
When data is received from the active Peer via the Communication Framework, you call the `ReplicatorConnection.receive` method.
220+
221+
[source]
222+
----
223+
include::android:example$codesnippet_collection.kt[tag=passive-peer-receive,indent=0]
224+
----
225+
226+
[#connection-teardown]
227+
== Connection Teardown
228+
229+
When a Peer disconnects from a Peer-to-Peer network, all connected Peers are notified.
230+
The disconnect notification is a good opportunity to close and remove a replication connection.
231+
The steps to Teardown the connection are slightly different depending on whether the active or passive Peer disconnects first.
232+
We will cover each case below.
233+
234+
[#initiated-by-active-peer]
235+
=== Initiated by Active Peer
236+
237+
image::ROOT:dis-active.png[]
238+
239+
[#active-peer-4]
240+
=== Active Peer
241+
242+
When an active Peer disconnects, it must call the `ReplicatorConnection.close` method.
243+
244+
[source]
245+
----
246+
include::android:example$codesnippet_collection.kt[tag=active-replicator-close,indent=0]
247+
----
248+
249+
Then, Couchbase Lite will call back your code through the `MessageEndpointConnection.close` to allow the application to disconnect with the Communication Framework.
250+
251+
[source]
252+
----
253+
include::android:example$codesnippet_collection.kt[tag=active-peer-close,indent=0]
254+
----
255+
256+
[#passive-peer-4]
257+
=== Passive Peer
258+
259+
When the passive Peer receives the corresponding disconnect notification from the Communication Framework, it must call the `ReplicatorConnection.close` method.
260+
261+
[source]
262+
----
263+
include::android:example$codesnippet_collection.kt[tag=passive-replicator-close,indent=0]
264+
----
265+
266+
Then, Couchbase Lite will call back your code through the `MessageEndpointConnection.close` to allow the application to disconnect with the Communication Framework.
267+
268+
[source]
269+
----
270+
include::android:example$codesnippet_collection.kt[tag=passive-peer-close,indent=0]
271+
----
272+
273+
[#initiated-by-passive-peer]
274+
=== Initiated by Passive Peer
275+
276+
image::ROOT:dis-passive.png[]
277+
278+
[#passive-peer-5]
279+
=== Passive Peer
280+
281+
When the passive disconnects, it must class the `MessageEndpointListener.closeAll` method.
282+
283+
[source]
284+
----
285+
include::android:example$codesnippet_collection.kt[tag=passive-stop-listener,indent=0]
286+
----
287+
288+
Then, Couchbase Lite will call back your code through the `MessageEndpointConnection.close` to allow the application to disconnect with the Communication Framework.
289+
290+
[source]
291+
----
292+
include::android:example$codesnippet_collection.kt[tag=passive-peer-close,indent=0]
293+
----
294+
295+
[#active-peer-5]
296+
=== Active Peer
297+
298+
When the active Peer receives the corresponding disconnect notification from the Communication Framework, it must call the `ReplicatorConnection.close` method.
299+
300+
[source]
301+
----
302+
include::android:example$codesnippet_collection.kt[tag=active-replicator-close,indent=0]
303+
----
304+
305+
Then, Couchbase Lite will call back your code through the `MessageEndpointConnection.close` to allow the application to disconnect with the Communication Framework.
306+
307+
[source]
308+
----
309+
include::android:example$codesnippet_collection.kt[tag=active-peer-close,indent=0]
310+
----
311+
312+
[#related-content]
313+
== Related Content
314+
++++
315+
<div class="card-row three-column-row">
316+
++++
317+
318+
[.column]
319+
=== {empty}
320+
.How to
321+
* xref:android:p2psync-websocket-using-passive.adoc[Passive Peer]
322+
* xref:android:p2psync-websocket-using-active.adoc[Active Peer]
323+
324+
325+
.
326+
327+
[.column]
328+
=== {empty}
329+
.Concepts
330+
* xref:android:landing-p2psync.adoc[Peer-to-Peer Sync]
331+
332+
* https://docs.couchbase.com/mobile/{major}.{minor}.{maintenance-android}{empty}/couchbase-lite-android/[API References]
333+
334+
.
335+
336+
337+
[.column]
338+
=== {empty}
339+
.Community Resources ...
340+
https://forums.couchbase.com/c/mobile/14[Mobile Forum] |
341+
https://blog.couchbase.com/[Blog] |
342+
https://docs.couchbase.com/tutorials/[Tutorials]
343+
344+
.
345+
xref:tutorials:cbl-p2p-sync-websockets:swift/cbl-p2p-sync-websockets.adoc[Getting Started with Peer-to-Peer Synchronization]
346+
15347

348+
++++
349+
</div>
350+
++++
16351

17-
include::{root-commons}p2psync-custom.adoc[subs="macros,attributes"]
18352

19-
include::{root-partials}block-related-content-p2psync.adoc[]

0 commit comments

Comments
 (0)