The ThingWorx Platform supports transfers of files both to and from the ThingWorx Platform. File transfers are performed over the WebSocket connection maintained with the ThingWorx Platform, so there is no need for the client application to open another connection.
To support file transfers in your client application, you must use a FileTransferVirtualThing to enable the functionality and define the directories available for file operations. A virtual directory maps a unique name to an absolute path of a directory in the file system. All subdirectories of the specified directory are exposed to the ThingWorx Platform. You can define multiple virtual directories. The directories do not need to be contiguous.
| As of v.6.1.0, the Java SDK uses WebSocket compression (per-message-deflate) by default for all WebSocket communications between the edge and the platform, including file transfers. In general, leaving compression enabled reduces the bandwidth used by the edge application but requires more memory and CPU usage. Choose whether to leave compression enabled, based on the capabilities of your devices and on the available bandwidth. Compression is enabled or disabled in the ClientConfigurator, using the compressionEnabled flag. Compression is enabled by default. |
You can define the maximum size of a file to be transferred and also retrieve the current setting for the parameter, using the following methods:
• setMaxFileSize — Use this method to specify the number of bytes that a file can contain before the transfer is rejected and an error message about the size is displayed. The default maximum size is 1 Gigabyte.
• getMaxFileSize — Use this method to retrieve the current setting for the maximum size of a file to be transferred.
| If you attempt to transfer a file that is larger than the maximum file size, the transfer fails with this error message: Size of source file ([source file size]) exceeds allowed maximum of [max file size]. |
You can also define how much data is sent inside each AlwaysOn message during a file transfer. Controlling this setting can have a dramatic effect on the speed of your file transfers. Two methods are available to set and retrieve the current value of this parameter:
• setBlockSize — Use this method to specify the amount of data (in bytes) to be transferred at a time during a file transfer. The default block size is 65536 bytes. This block size is recommended as a best practice to achieve optimal performance when transferring large files.
• getBlockSize — Use this method to retrieve the current setting for the amount of data to be transferred at a time during a file transfer.
The following example creates a simple client configuration with the URI of a local ThingWorx Platform, an application key that is retrieved using the password callback method, and the developer-friendly ignoreSSLErrors parameter set to true. It also sets the maximum file size for a file transfer and the block size for files that are to be separated into chunks for the transfer and reassembled at the destination. It then creates the ConnectedThingClient.
Next, the FileTransferVirtualThing is created. Then, two virtual directories that will act as the root directories in the virtual file system of this application are added. The client is set up to send the BIND message, and then the client is started. Compression is enabled by default so no line of code is needed here to enable it.
The While loop keeps the client “awake” to give a user of ThingWorx Composer the time to send a request. To catch any possible exceptions, a try/catch is set up.
// Create a client config
ClientConfigurator config = new ClientConfigurator();
// Basic configuration
config.setUri("wss://localhost:443/Thingworx/WS");
config.setSecurityClaims(new SamplePasswordCallback);
config.ignoreSSLErrors(true);
config.setMaxFileSize(1000);
config.setBlockSize(1024000);
try {
ConnectedThingClient client = new ConnectedThingClient(config);
FileTransferVirtualThing myThing = new FileTransferVirtualThing(ThingName,
"File Transfer Example", client);
// Add two virtual directories that will act as the root directories in this
// virtual file system of this application.
myThing.addVirtualDirectory("in", "/home/username/files/in");
myThing.addVirtualDirectory("out", "/home/username/files/out");
client.bindThing(myThing);
client.start();
while(!client.isShutdown()) {
Thread.sleep(5000);
}
} catch(Exception e) {
e.printStackTrace();
}
Once it connects to the platform, this client binds its FileTransferVirtualThing to the appropriate Remote Thing on the platform. The Remote Thing on the platform must be created, using either the RemoteThingWithFileTransfer Thing Template or the RemoteThingWithTunnelsAndFileTransfer Thing Template. Once bound, the various file system services that are available in the Remote Thing can be used to interact with the file system of the client machine. The Thing inherits these services from the RemoteThingWithFileTransfer Thing Template.
For example, from the platform, a user can call the BrowseDirectory service of the Remote Thing. If a forward slash (‘/’) is used for the path parameter, the two configured virtual directories would be returned. If /logs were passed in, a list of the files and directories in <user_home>/logs would be returned.
Refer also to the topics,
File Transfers in the section, "ThingWorx Concepts", and to
Transfer Files Using the Copy Service in the "How to" section of this help center.