The Connectivity Plugin for Xamarin is my second most installed NuGet package with nearly 600,000 installs at time of writing this. It is easy to see why as it gives developers the ability to check connectivity on any platform with a single line of code, subscribe to events, and see what the current connection type is, with a complete cross platform API for iOS, Android, macOS, and Windows.
I mean look at this thing, it is beautiful:
if(CrossConnectivity.Current.IsConnected)
{
//You are connected to the internet!!!
}
However, there is a feature that isn't used as much that let's developers ping a local or remote host to see if the device can connect to it. This is often good to use when you want to see if your web host or API is up and running before making full network calls to pull down data.
This "Ping" support was implemented a few different ways across iOS, Android, and Windows, which lead to a few rare issues based on how the developers were using the API. This has all changed with the standardization of checking for reachability in version 4.0, which is available in pre-release today, and took me a long time and a lot of code to refactor with Frank Krueger. So much that I even tweeted about it.
Re-wrote nearly 25% of the Connectivity Plugin today with @praeclarum!!! Much improvement coming :)
— James Montemagno (@JamesMontemagno) August 12, 2017
API Changes
In the past the API wasn't really clear if developers should use:
Task<bool> IsReachable(string host, int msTimeout = 5000);
or
Task<bool> IsRemoteReachable(string uri, int port = 80, int msTimeout = 5000);
In addition, what is with the weird port and what is with timeout in milliseconds! The API is now much cleaner:
Use:
- IsReachable: to check a hostname such as a machine name or IP address
- IsRemoteReachable: to check reachability of a full valid URI
They now take in a bit different parameters:
Task<bool> IsReachable(string host, TimeSpan timeout);
Task<bool> IsRemoteReachable(string uri, TimeSpan timeout);
Task<bool> IsRemoteReachable(Uri uri, TimeSpan timeout);
This means that you can simply add the port into the URI or the string, which will be converted to a URI.
Notice that everything now uses TimeSpan for the timeout :) very nice!
Under the hood upgrades
One of the original problems with IsReachable on iOS/macOS was that there is actually no built in APIs to ping a local IP address or hostname. This is why I asked very nicely for our components team to create a C# binding around Apple's SimplePing and push it up to NuGet so I can consume it!
On Android things are even more tricky as the old code only attempted to use Java.Net.InetAddress to check for reachability.... which actually doesn't work with hostnames. Now, it detects if you passed it an IP Address and checks, else simply just attempts to resolve the actual hostname.
When it comes to IsRemoteReachable each platform was using different mechanisms to do the same thing. This is no good! This is .NET and we have Sockets! Every platform now uses Socket Streams as their core.
Test it today
If you are using the Connectivity Plugin with these methods in your application, I encourage you to test it out today and give feedback on GitHub.