website logo
Legacy DocsPortal
⌘K
Welcome to Ditto
Onboarding
Ditto Basics
SDK Setup Guides
Platform Manual
HTTP API
Kafka Connector
Use Cases
FAQs
Troubleshooting Guide
Support
Docs powered by
Archbee
Platform Manual
Transports

Configuring Transports

25min

This topic provides how-to instructions and general information to effectively enable and disable transports and ensure seamless and secure connections.

Although Ditto automatically attempts to connect to other instances on the Local Area Network (LAN), Bluetooth Low Energy (LE), and Apple Wireless Direct Link (AWDL), supplying a DittoTransportConfig does not enable this feature by default.

You must manually enable peer-to-peer connections using EnableAllPeerToPeer(). For instructions, see Enabling and Disabling Transports.

Configuring Additional Settings

To configure additional connection settings for the current Ditto instance, before calling startSync(), construct a DittoTransportConfig value and set it using ditto.SetTransportConfig.

Enabling and Disabling Transports

You can enable and disable transport protocols for all connected Small Peers by doing either of the following.


  • To enable all transport protocols at once, configure EnableAllPeertoPeer( ).
  • To enable transport protocols separately, configure a transport protocol one at a time, as shown in the following example.

Swift
Kotlin
JS
Java
C#
C++
Rust
|
// Create a new DittoTransportConfig()
var config = DittoTransportConfig()

//Enable all peer to peer transports
config.enableAllPeerToPeer()

//Or enable/disable each transport separately
//BluetoothLe
config.peerToPeer.bluetoothLE.isEnabled = true
//Local Area Network
config.peerToPeer.lan.isEnabled = true
//Awdl
config.peerToPeer.awdl.isEnabled = true

ditto.transportConfig = config

do {
  try ditto.startSync()
} catch (let err) {
  print(err.localizedDescription)
}


There are instances where you may want to configure additional connections configurations for the current Ditto instance. This section will teach you how to configure your Ditto instance to listen for connections on a port explicitly and to connect to remote instances via a host (IP) and port. To do this, before you call startSync(), construct a DittoTransportConfig value and set ditto.setTransportConfig.

Ditto will automatically attempt to connect to other ditto instances on the Local Area Network, Bluetooth, and AWDL. However, if you supply a DittoTransportConfig, this will not automatically be enabled. You'll need to remember to enable peer to peer connections with EnableAllPeerToPeer().



Syncing with Big Peer

The Big Peer generates certificates automatically for each Small Peer. A certificate involves an expiration date and AppID, among other credentials. Read more here about how it works.

In order to sync with other devices, a peer must connect to the Big Peer at least once. To do this, you must use either OnlinePlayground or OnlinewithAuthentication.

We recommend using OnlinePlayground for development and OnlineWithAuthentication for production apps. If you only want to use the Big Peer for authentication without syncing to the cloud, you can use enableDittoCloudSync=false.

By default, enableDittoCloudSync is set to true.


Swift
Kotlin
JS
Java
C#
C++
Rust
|
let ditto = Ditto(identity: .onlinePlayground(
    appID: "REPLACE_ME_WITH_YOUR_APP_ID",
    token: "REPLACE_ME_WITH_YOUR_PLAYGROUND_TOKEN",
    // Set to false to disable syncing with the cloud
    enableDittoCloudSync: true
))
do {
  try ditto.startSync()
} catch (let err) {
  print(err.localizedDescription)
}


Observing Peers​

Ditto always monitors the mesh network and can report the device names of peers it is connected to. You can manually set the device name of those peers and observe those peers in the network.

The device name must be set before startSync() is called.


Swift
Kotlin
JS
Java
Rust
|
ditto.deviceName = "Susan B.";
try {
    ditto.startSync();
} catch(DittoError e) {
    // handle error
}
ditto.getPresence().observe(peers -> {
    // render peers
});


If you want to observe changes made by a particular device, include the device name as a field in the document and query for that field in your ditto live query.


pseudocode
|
"status == 'open' && edited_by == 'deviceC'"


Sync Groups

By default, devices with the same app ID automatically form a mesh network to connect with one another.

However, you can streamline replication processes, minimize unnecessary data transfer, and optimize resource usage by configuring distinct groups.



The sync groups feature is not supported in Java.

Sync groups are an optimization, not a security control. If a connection is created manually, such as by specifying a connect transport, then devices from different sync groups will still sync as normal. If two groups of devices are intended to have access to different data sets, this must be enforced using Ditto's permissions system.



The syncGroup parameter provides this functionality. A device can only ever be in one sync group, which by default is group 0. Up to 2^32 distinct group numbers can be used in an app. Using a sync group is more performant, and is recommended in any case where this knowledge is known ahead of time.



For example, the following graphic illustrates two distinct restaurants identified by their location IDs: 7890 and 1234. When a peer establishes its identity with the Big Peer, it includes its location ID as part of the authentication callback.

Now, the two groups maintain isolated mesh networks:

Document image


Swift
Kotlin
JS
Java
C#
C++
Rust
|
// not supported in Java


Connecting to Remote Small Peers

If you know the host and port of another remote Ditto peer and would like to connect to it, construct a DittoTransportConfig object and add the host and port to the DittoTransportConfig.Connect.TcpServers property as a string. The string format should be host:port, separated by a colon.

In the example below, we know of two other Ditto peers located on:

  • Host IP 135.1.5.5 at port 12345
  • Host IP 185.1.5.5 at port 4567

Swift
Kotlin
JS
Java
C#
C++
Rust
|
auto config = ditto::TransportConfig();
// Connect explicitly to remote devices
config.connect.tcp_servers.insert("135.1.5.5:12345");
config.connect.tcp_servers.insert("185.1.5.5:12345");

// set the transport config
ditto.set_transport_config(config);
// now you can start ditto's sync
ditto.start_sync();


Feel free to add as many known remote host:port strings.

You can also configure your Ditto instance to connect to a websocket, which is useful to connect to one or more big peers or authentication instances.


Swift
Kotlin
JS
Java
C#
C++
Rust
|
// not supported in Java


Listening for Connections

You can enable the Ditto instance to listen for incoming connections from other remotes Ditto peers on a specific port. You can think of this as setting up your Ditto as a "server" that can listen to connections from other peers.

In this example, we would like our Ditto instance to listen to incoming connections on port 4000 on 0.0.0.0.

To be safe, please do not use localhost when setting the IP interface. Use "0.0.0.0" instead.


Swift
Kotlin
JS
Java
C#
C++
Rust
|
import { TransportConfig } from '@dittolive/ditto'

const config = new TransportConfig()
config.listen.tcp.isEnabled = true
config.listen.tcp.interfaceIP = '0.0.0.0'
config.listen.tcp.port = 4000
ditto.setTransportConfig(config)
ditto.startSync()


Incoming connections from other Ditto peers will be able to connect only if the port is accessible. Depending on your deployment be sure to check that external connections can reach the port that you have specified in your configuration. You may need to set up port forwarding if external ports map differently to your host.



Combining Multiple Transports

You can specify several modes of transport configuration within DittoTransportConfig. The following snippet shows you a ditto instance that can:

  • Connect to local area network devices
  • Listen for incoming remote connections
  • Connect to remote devices with a known host and port.

Swift
Kotlin
JS
Java
C#
C++
Rust
|
import { TransportConfig } from '@dittolive/ditto'

const config = new TransportConfig()
if (isNode() && OS === 'darwin') {
// 1. Enable All Peer to Peer Connections (not in a browser environment)
config.setAllPeerToPeerEnabled(true)
// 2. Listen for incoming connections on port 4000
config.listen.tcp.isEnabled = true
config.listen.tcp.interfaceIP = '0.0.0.0'
config.listen.tcp.port = 4000

// 3. Connect explicitly to remote devices
ditto.setTransportConfig(config)
ditto.startSync()


Monitoring Conditions

If syncing over Bluetooth LE is a critical part of your application you may want to warn the user if they are missing the permission or if the hardware is disabled. Ditto will help you by reporting conditions via a delegate or callback object.

First, while configuring Ditto, assign a delegate or a callback to receive notifications.


Swift
Kotlin
JS
Java
C#
C++
Rust
|
// Setting up inside a ViewController
let ditto = Ditto(identity: DittoIdentity.onlinePlayground(appID: "REPLACE_ME_WITH_YOUR_APP_ID", token: "REPLACE_ME_WITH_YOUR_PLAYGROUND_TOKEN"))
ditto.delegate = self
try! ditto.startSync()

// Now you can observe real time changes to the transport conditions:
extension ViewController: DittoDelegate {
   func transportConditionDidChange(transportID: Int64, condition: TransportCondition) {
       if condition == .BleDisabled {
           print("BLE disabled")
       } else if condition == .NoBleCentralPermission {
           print("Permission missing for BLE")
       } else if condition == .NoBlePeripheralPermission {
           print("Permission missing for BLE")
       }
   }




Updated 27 Sep 2023
Did this page help you?
PREVIOUS
Transports
NEXT
Setting Up BlueZ for iOS-to-Linux Communication
Docs powered by
Archbee
TABLE OF CONTENTS
Configuring Additional Settings
Enabling and Disabling Transports
Syncing with Big Peer
Observing Peers​
Sync Groups
Connecting to Remote Small Peers
Listening for Connections
Combining Multiple Transports
Monitoring Conditions
Docs powered by
Archbee