Short story: To avoid the overhead of opening an outbound TCP connection, a device handler is attempting to send UDP. The statement
socket = new DatagramSocket()results in an error
java.lang.SecurityException: Creating new class java.net.DatagramSocket is not allowed
Of course, I’m not trying to create a new class, only a new instance of an existing class. The documentation has a general note “SmartThings allows only certain classes to be used in the sandbox. A SecurityException will be thrown if using a class that is not allowed.” but I don’t see why something as innocuous as UDP packets would be prohibited, nor why the error message would be misleading.
How can I eliminate or work around this error?
In detail:
I’m new to ST and am starting with only legacy devices. First app controls room lights with various motion detectors as inputs. Response time was unacceptably slow. Much of the delay was caused by overhead network activity. Here is a Wireshark capture taken on my bridge (an old netbook), before performance improvements:
As you can see, the bridge starts to send the motion alert at :02.110 (pkt. 5242) and doesn’t get the resulting command until :02.894 (pkt 5296), a delay of 784 milliseconds. However, the ST’s actual response time is only from pkt. 5264 to pkt. 5293, about 309 ms (incl. ~100 ms network time), i.e. there is 475 ms overhead! One of my locations (Bangkok) is ~300 ms ping time from Amazon Virginia, so eliminating this overhead is essential.
When presenting status changes, I was able to eliminate the DNS/TCP/TLS overhead by having the bridge open an SSL connection to graph.api.smartthings.com at initialization and keeping it alive by sending a “HEAD /” request once per minute. Then, when motion is detected, it can send the application data immediately. The server seems to accept pipelined requests, so this works even if a keep-alive was just sent and not yet acknowledged. I’ll provide details and/or code fragments (in perl) if anyone is interested.
However, I’m stumped trying to get a command sent without delay. It may be possible to have an API endpoint handler “hang”; when a command needs to be sent the handler would return it as “response” information. However, I don’t know how to do the control flow, or if it’s even possible with ST. I also thought about encoding the command in a DNS request, but it’s not clear how to keep the NS record for the subdomain cached at ST, given its propensity to use many servers for outbound requests.
All suggestions welcome. Thanks.