ThingWorx Edge SDKs: Tutorial > The Connection Process
The Connection Process
All connections follow a basic workflow, shown in the following diagram and described below it:
The Connection Workflow
The following steps explain how the connection process works:
1. An HTTP/HTTPS connection is started.
2. The connection gets a WebSockets upgrade (AlwaysOn protocol).
3. The device authenticates with the ThingWorx Platform using an application key. After authenticating with the platform, a device can call InvokeService().
4. Binding takes place. Binding connects a Thing to a Device, setting its isConnected property to true. It also registers a Thing to participate in property change subscriptions. A side-effect of binding is that properties and services of a Thing are mapped to values and functions on your device.
* 
If the version of your ThingWorx Platform is 8.4.0 or later, an additional property, called isReporting, also serves as an indicator of whether the device is bound and currently communicating with the platform.
5. After binding is complete, the synchronization process runs. During this process, the platform calls notifyPropertyUpdate on each bound Thing to provide configuration information that is stored on the platform.
6. The device sends property changes messages to the ThingWorx Platform, an operation called "pushing data".
* 
Pushing data before synchronization causes data loss!
The following figures illustrate the Edge SDK connection sequence in more detail:
Connection Details, Part 1
Connection Details, Part 2
The following examples show how to connect to the ThingWorx Platform using the ThingWorx Edge C SDK and the ThingWorx Edge Java SDK.
Example 1. Connection Example from Steam Sensor main.c - C SDK
#include "twExt.h"

#include "SteamThing.h"

/* Server Defaults */
#define TW_HOST "localhost"
#define DATA_COLLECTION_RATE_MSEC 5000
#define DEFAULT_THING_NAME "SteamSensor"
#define RETRY_COUNT 3

#if defined NO_TLS
#define TW_PORT 8080
#else
#define TW_PORT 443
#endif

char* appKey = TW_APP_KEY;

void bindEventHandler(char *entityName, char isBound, void *userdata) {
/* First NULL says "tell me about all things that are bound */
if (isBound) TW_LOG(TW_FORCE,"bindEventHandler: Entity %s was Bound", entityName);
else TW_LOG(TW_FORCE,"bindEventHandler: Entity %s was Unbound", entityName);
}

void authEventHandler(char *credType, char *credValue, void *userdata) {
/* Callbacks only when we have connected & authenticated */
if (!credType || !credValue) return;
TW_LOG(TW_FORCE,"authEventHandler: Authenticated using %s = %s. Userdata = 0x%x", credType, credValue, userdata);
}

void synchronizeStateHandler(char *entityName, twInfoTable *subscriptionInfo, void *userdata){
/*
* Called after binding to notify your application about what fields are bound on the server.
* Will also be called each time bindings on a thing are edited.
*/
TW_LOG(TW_FORCE,"synchronizeStateHandler: Entity %s was synchronized with your ThingWorx Server", entityName);
}

/**
* The app key callback function is called whenever the SDK requires the current app key to authenticate
* In production, this callback should obtain an app key from a secure source.
* @param appKeyBuffer a buffer allocated and provided to cop
* @param maxLength the size of appKeyBuffer. Do not return a password longer than this length.
*/
void appKeyCallback(char* appKeyBuffer,unsigned int maxLength){
strncpy(appKeyBuffer,appKey,maxLength);
}

int main( int argc, char** argv ) {
int err = 0;

/* Allow the user to override the default values for connection settings
using command line arguments */
char * thingName = DEFAULT_THING_NAME;
char* hostname = TW_HOST;
int16_t port = TW_PORT;

/* Parse command line parameters */
if(argc == 1){
printf("Syntax: %s <hostname> <port> <appKey> <thingname>\n",argv[0]);
exit(0);
}
if(argc > 1){
hostname = argv[1];
}
if(argc > 2){
port = (short)atoi(argv[2]);
}
if(argc > 3){
appKey = argv[3];
}
if(argc > 4){
thingName = argv[4];
}

/* Configure Logging */
twLogger_SetLevel(TW_TRACE);
twLogger_SetIsVerbose(TRUE); /* Will show all messages network at TRACE level, reduces performance */
TW_LOG(TW_FORCE, "Starting up...");

/* Initialize the API */
err = twApi_Initialize(hostname, port, TW_URI, appKeyCallback, NULL, MESSAGE_CHUNK_SIZE, MESSAGE_CHUNK_SIZE, TRUE);
if (TW_OK != err) {
TW_LOG(TW_ERROR, "Error initializing the API");
exit(err);
}
Example 2. Connection Example - Java SDK

import com.thingworx.communications.client.ClientConfigurator;
import com.thingworx.communications.client.ConnectedThingClient;
import com.thingworx.communications.common.SecurityClaims;public
class JavaSDKExample extends ConnectedThingClient {
public JavaSDKExample(final ClientConfigurator config) throws Exception {super(config);}

public static void main(String[] args) throws Exception {
ClientConfigurator config = new ClientConfigurator();
config.setUri("ws://<ip_address>:8080/Thingworx/WS");
config.setSecurityClaims(SecurityClaims.fromAppKey("<Application_Key>"));
config.ignoreSSLErrors(true); // All self-signed certs
// Create the client passing in the configuration from above
JavaSDKExample client = new JavaSDKExample(config);
client.start(); // Start threads to process messages and monitor your connection

// As long as the client has not been shutdown, continue
while(true) {
Thread.sleep(1000);
}
}
}
Was this helpful?