Data Sync
Customizing Transport Configurations
this article provides instructions on explicitly configuring your ditto instance to listen for connections on a specific port and to connect to remote instances using a host (ip) and port 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 rather, y ou manually enable peer to peer connections using enableallpeertopeer() 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 // 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) }val config = dittotransportconfig() //enable all peer to peer transports config enableallpeertopeer() //or enable/disable each transport separately //bluetoothle config peertopeer bluetoothle enabled = true //local area network config peertopeer lan enabled = true //wifi aware config peertopeer wifiaware enabled = true ditto transportconfig = config ditto startsync()const config = new transportconfig() // enable all peer to peer transports config setallpeertopeerenabled(true) // 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 settransportconfig(config) ditto startsync()dittotransportconfig config = new dittotransportconfig(); //enable all peer to peer transports config enableallpeertopeer(); //or enable/disable each transport separately //bluetoothle config getpeertopeer() getbluetoothle() setenabled(true); //local area network config getpeertopeer() getlan() setenabled(true); //awdl config getpeertopeer() getwifiaware() setenabled(true); ditto settransportconfig(config); try { ditto startsync(); } catch(dittoerror error) { // handle error }dittotransportconfig config = new dittotransportconfig(); //enable all peer to peer transports config enableallpeertopeer(); //or enable/disable each transport separately //bluetoothle config peertopeer bluetoothle enabled = true; config peertopeer bluetoothle enabled = true; //local area network config peertopeer lan enabled = true; //awdl config peertopeer awdl enabled = true; ditto transportconfig = config; ditto startsync();// not supported // not supported configuring additional settings if you need additional connection configurations for the current ditto instance, configure it to listen for connections on a specific port and to connect to remote instances using a host (ip) and port b efore calling startsync() , create a dittotransportconfig object with the desired settings u sing the ditto settransportconfig api method, set the created object on your ditto instance call the startsync method on your ditto instance to initiate sync with the configured settings 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 digital identities 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 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) }val config = dittotransportconfig() //enable all peer to peer transports config enableallpeertopeer() //or enable/disable each transport separately //bluetoothle config peertopeer bluetoothle enabled = true //local area network config peertopeer lan enabled = true //wifi aware config peertopeer wifiaware enabled = true ditto transportconfig = config ditto startsync()const identity identity = { type '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, } const path = ' /your ditto application data path' const ditto = new ditto(identity, path) ditto startsync()dittoidentity identity = new dittoidentity onlineplayground(androiddependencies, "replace me with your app id", "your playground token here", // set to false to disable syncing with the cloud true); ditto ditto = new ditto(androiddependencies, identity); try { ditto startsync(); } catch(dittoerror e) { //handle error }try { var ditto = new ditto(dittoidentity 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), path); ditto startsync(); } catch (dittoexception ex) { console writeline($"ditto error {ex message}"); }// not supported // not supported 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 ditto devicename = "susan b " let observer = ditto presence observe { presence in // render peers } do { try ditto startsync() } catch (let err) { print(err localizeddescription) }ditto devicename = "susan b " ditto startsync() peersobserver = ditto presence observe { graph > // render peers }ditto devicename = "susan b " ditto startsync() peersobserver = ditto presence observe({ graph > // render peers })ditto devicename = "susan b "; try { ditto startsync(); } catch(dittoerror e) { // handle error } ditto getpresence() observe(peers > { // render peers });// not supported 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'" 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, using string format host\ port separated by a colon, add the host and port to the dittotransportconfig connect tcpservers property for example, the following indicates there are two other small peers known to ditto and provides details of their network locations, including the ip addresses and port numbers associated with each peer host ip 135 1 5 5 at port 12345 host ip 185 1 5 5 at port 4567 var config = dittotransportconfig() // connect explicitly to a remote devices config connect tcpservers insert("135 1 5 5 12345") config connect tcpservers insert("185 1 5 5 12345") ditto transportconfig = config do { try ditto startsync() } catch (let err) { print(err localizeddescription) }val transportconfig = dittotransportconfig() transportconfig connect tcpservers add("135 1 5 5 12345") transportconfig connect tcpservers add("185 1 5 5 12345") ditto transportconfig = transportconfig ditto startsync()import { transportconfig } from '@dittolive/ditto' const config = new transportconfig() config connect websocketurls push('wss\ //135 1 5 5 12345') config connect websocketurls push('wss\ //185 1 5 5 12345') ditto settransportconfig(config) ditto startsync()dittotransportconfig config = new dittotransportconfig(); dittoconnect connect = new dittoconnect(); connect settcpservers(sets newhashset("135 1 5 5 12345", "185 1 5 5 12345")); config setconnect(connect); try { ditto startsync(); } catch(dittoerror error) { // handle error }dittotransportconfig transportconfig = new dittotransportconfig(); // connect explicitly to a remote device on transportconfig connect tcpservers add("135 1 5 5 12345"); // you can add as many tcpservers as you would like transportconfig connect tcpservers add("185 1 5 5 4567"); // set the transport config ditto transportconfig = transportconfig; // now you can start ditto's sync ditto startsync();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();let mut config = transportconfig new(); // empty config connect tcp servers insert("135 1 5 5 12345" to string()); // custom tcp listener config connect tcp servers insert("185 1 5 5 12345" to string()); // custom tcp listener config connect websocket urls insert("wss\ //example com" to string()); // custom ws endpoint ditto set transport config(config); ditto start sync()?; initializing websocket connections e nsure websocket connections are discoverable across peers within your local network // not supported in swiftval config = dittotransportconfig() config connect websocketurls add("ws\ //127 0 0 1") ditto transportconfig = config ditto startsync()import { transportconfig } from '@dittolive/ditto' const config = new transportconfig() config connect websocketurls push('ws\ //127 0 0 1') ditto settransportconfig(config) ditto startsync()// not supported in javadittotransportconfig config = new dittotransportconfig(); config connect websocketurls add("ws\ //127 0 0 1"); ditto transportconfig = config; ditto startsync();// not supported in c++//not supported in rust 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 var config = dittotransportconfig() // 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 ditto transportconfig = config do { try ditto startsync() } catch (let err) { print(err localizeddescription) }val transportconfig = dittotransportconfig() transportconfig connect tcpservers add("135 1 5 5 12345") transportconfig connect tcpservers add("185 1 5 5 12345") ditto transportconfig = transportconfig ditto startsync()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()dittotransportconfig config = new dittotransportconfig(); config enableallpeertopeer(); dittolisten listen = new dittolisten(); dittotcplistenconfig tcplistenconfig = new dittotcplistenconfig(); tcplistenconfig setenabled(true); tcplistenconfig setinterfaceip("0 0 0 0"); tcplistenconfig setport(4000); listen settcp(tcplistenconfig); config setlisten(listen); try { ditto startsync(); } catch(dittoerror error) { // handle error }dittotransportconfig transportconfig = new dittotransportconfig(); transportconfig listen tcp = new dittotcplistenconfig(); // by default listen tcp enabled is false, be sure to set it to true transportconfig listen tcp enabled = true; // if you want to listen on localhost, most likely you will use 0 0 0 0 // do not use "localhost" as a string transportconfig listen tcp interfaceip = "0 0 0 0"; // specify your port transportconfig listen tcp port = 4000; ditto transportconfig = transportconfig; // now you can call `ditto startsync()` ditto startsync();auto config = ditto transportconfig(); config listen tcp enabled = true; config listen http enabled = false; config listen tcp interface ip = "0 0 0 0"; config listen tcp port = 4000; ditto set transport config(config); ditto start sync();let mut config = transportconfig new(); // empty config listen tcp enabled = true; config listen tcp interface ip = "0 0 0 0" to string(); config listen tcp port = 4000; config listen http enabled = false; ditto set transport config(config); ditto start sync()?; 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 var config = dittotransportconfig() // 1 enable all peer to peer connections config enableallpeertopeer() // 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 config connect tcpservers insert("135 1 5 5 12345") config connect tcpservers insert("185 1 5 5 12345") ditto transportconfig = config do { try ditto startsync() } catch (let err) { print(err localizeddescription) }val transportconfig = dittotransportconfig() // 1 enable all peer to peer connections transportconfig enableallpeertopeer() // 2 listen for incoming connections on port 4000 transportconfig listen tcp enabled = true transportconfig listen http enabled = false transportconfig listen tcp interfaceip = "0 0 0 0" transportconfig listen tcp port = 4000 // 3 connect explicitly to remote devices transportconfig connect tcpservers add("135 1 5 5 12345") transportconfig connect tcpservers add("185 1 5 5 12345") ditto transportconfig = transportconfig ditto startsync()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()dittotransportconfig config = new dittotransportconfig(); // 1 enable peer to peer connections config enableallpeertopeer(); // 2 listen for incoming connections on port 4000 dittolisten listen = new dittolisten(); dittotcplistenconfig tcplistenconfig = new dittotcplistenconfig(); tcplistenconfig setenabled(true); tcplistenconfig setinterfaceip("0 0 0 0"); tcplistenconfig setport(4000); listen settcp(tcplistenconfig); config setlisten(listen); // 3 connect explicitly to remote devices dittoconnect connect = new dittoconnect(); connect settcpservers(sets newhashset("135 1 5 5 12345", "185 1 5 5 12345")); config setconnect(connect); try { ditto startsync(); } catch(dittoerror error) { // handle error }dittotransportconfig transportconfig = new dittotransportconfig(); // 1 enable local area network connections transportconfig enableallpeertopeer(); // 2 listen for incoming connections on port 4000 transportconfig listen tcp enabled = true; transportconfig listen tcp interfaceip = "0 0 0 0"; transportconfig listen tcp port = 4000; // 3 connect explicitly to remote devices transportconfig connect tcpservers add("135 1 5 5 12345"); transportconfig connect tcpservers add("185 1 5 5 12345"); ditto transportconfig = transportconfig; ditto startsync();auto config = ditto transportconfig(); // 1 enable all peer to peer connections config enable all peer to peer(); // 2 listen for incoming connections on port 4000 config listen tcp enabled = true; config listen http enabled = false; config listen tcp interface ip = "0 0 0 0"; config listen tcp port = 4000; // 3 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"); ditto set transport config(config); ditto start sync();let mut config = transportconfig new(); // empty // 1 enable auto discovery of peer to peer connections config enable all peer to peer(); // auto connect via lan and bluetooth // 2 configure tcp listener config listen tcp enabled = true; config listen tcp interface ip = "0 0 0 0" to string(); config listen tcp port = 4000; config listen http enabled = false; // 3 configure explicit, hard coded connections config connect tcp servers insert("135 1 5 5 12345" to string()); // custom tcp listener config connect websocket urls insert("wss\ //example com" to string()); // custom ws endpoint ditto set transport config(config); ditto start sync()?; 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 // 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") } }// setting up inside an activity val androiddependencies = defaultandroiddittodependencies(applicationcontext) val ditto = ditto(androiddependencies, dittoidentity onlineplayground (androiddependencies, appid = "replace with app id", token = "replace me with your playground token")) ditto callback = this ditto startsync() // now you can observe real time changes to the transport conditions class mainactivity appcompatactivity(), dittocallback { override fun transportconditiondidchange(transportid long, condition transportcondition) { var toasttext string? = null if (condition == transportcondition transport condition ble disabled) { toasttext = "ble disabled" } else if (condition == transportcondition transport condition no ble central permission) { toasttext = "permission missing for ble" } else if (condition == transportcondition transport condition no ble peripheral permission) { toasttext = "permission missing for ble" } toasttext? let { handler(mainlooper) post { toast maketext(this, it, toast length long) show() } } } }const transportconditionsobserver = ditto observetransportconditions((condition, source) => { if (condition === 'bledisabled') { console log('ble disabled') } else if (condition === 'noblecentralpermission') { console log('permission missing for ble') } else if (condition === 'nobleperipheralpermission') { console log('permissions missing for ble') } })// setting up inside an activity defaultandroiddittodependencies androiddependencies = new defaultandroiddittodependencies(getapplicationcontext()); ditto ditto = new ditto(androiddependencies, new dittoidentity onlineplayground(androiddependenciesone, "replace with app id")); ditto callback = this; ditto startsync(); // now you can observe real time changes to the transport conditions public class mainactivity extends appcompatactivity implements dittocallback { @override public void transportconditiondidchange(@notnull dittotransportcondition condition, @notnull dittoconditionsource transportid) { string toasttext = null; if (condition == dittotransportcondition bledisabled) { toasttext = "ble disabled"; } else if (condition == dittotransportcondition noblecentralpermission) { toasttext = "permission missing for ble"; } else if (condition == dittotransportcondition nobleperipheralpermission) { toasttext = "permission missing for ble"; } if (toasttext != null) { string finaltoasttext = toasttext; runonuithread(new runnable() { @override public void run() { toast maketext(mainactivity this, finaltoasttext, toast length long) show(); } }); } } }// not supported in c#// not supported in c++// not supported in rust