Publically exposing a service on my laptop using the AppFabric Service Bus

To learn a bit more about the AppFabric Service Bus in Azure, I am creating a relatively simple solution and documenting it as I go in this blog post.

The idea: Create a WCF (REST/JSON) service that runs on my laptop and exposes a public endpoint on the Service Bus that I can connect to from any browser to find out where my laptop is physically located. The service must work as long as there is an active Internet connection, even if the computer is behind various firewalls and with NAT.

In other words, very similar to various “Find my device” services that exist, but this one will be even more rough and inaccurate in its positioning ;).

Round 1 – Create Service Bus namespace

First I needed to create a service bus namespace where my service will be exposed. This is done via the Windows Azure Management Portal. First, navigate to the Service Bus tab and click to create a new service namespace:

Then fill in the unique namespace name that you want and select a region, subscription and connection pack size. The connection pack size has an effect on cost, and I will choose “0 connections” which basically means pay-as-you-go (but at a higher per connection cost than if I would have selected a fixed package size). More information about pricing for the Service Bus can be found here.

That is all that’s needed to create the namespace. Note that there is a button to retrieve a key that we will need later on to publish the service to this namespace

Round 2 – Creating an application that exposes a service on the Service Bus

The next phase is to develop the actual application that will host the service and expose the endpoint on the AppFabric Service Bus. I will do this in a simple Console Application, even though it would be very easy for someone who steals my laptop to shut down the application and stop me from finding it :).

First, we need to reference Microsoft.ServiceBus.dl which comes with the Windows Azure AppFabric SDK and is located in the following folder after installation:
C:\Program Files\Windows Azure AppFabric SDK\V1.5\Assemblies\NET4.0

The target framework for the project has to be changed to the full “.NET Framework 4” to expose a WCF service:

Exposing the service is very similar to creating a “normal” WCF service. One difference is a specific helper method for creating the URI for your service. In the example below the first parameter is the protocol prefix, the second parameter is the service namespace, and the last parameter is the relative path that the service will be exposed on:

ServiceBusEnvironment.CreateServiceUri("https", "findmylaptopdemo", "findmylaptop");

The resulting URL for the service methods will be:
https://findmylaptopdemo.servicebus.windows.net/findmylaptop/METHODNAME

We then need to specify a relay binding, in my case a WebHttpRelayBinding which is recommended for WCF REST implementations. I specify to not require any authentication from the clients:

var binding = new WebHttpRelayBinding();
binding.Security.RelayClientAuthenticationType = RelayClientAuthenticationType.None;

The next thing to create a behavior with the issuer name and secret. This is required to add the service to the AppFabric service namespace. You get the secret and issuer name (default=owner) from the Management Portal as described earlier.

var behavior = new TransportClientEndpointBehavior();
behavior.TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(IssuerName, IssuerSecret);

The last step involves defining the interface and writing the code for the service, just like with any service. Part of the  service interface:

[ServiceContract]
public interface IFindMyLaptopService
{
[OperationContract]
[WebInvoke(
Method = "GET",
UriTemplate = "/ip")]
Stream GetIp();
}

The code for the derived method:

public Stream GetIp()
{
Console.WriteLine("Incoming request for GetIp(), getting and returning external IP:");

var ip = WhatIsMyIpService.GetExternalIpAddress();
Console.WriteLine(ip);
Console.WriteLine("");

var html = string.Format("<html><body>Laptop's IP address: {0}</body></html>", ip);

return new MemoryStream(System.Text.Encoding.UTF8.GetBytes(html));
}

The helper method to retrieve the IP from WhatIsMyIp:

public static IPAddress GetExternalIpAddress()
{
const string whatIsMyIpUrl = "<a href="http://automation.whatismyip.com/n09230945.asp">http://automation.whatismyip.com/n09230945.asp</a>";
var webClient = new WebClient();
var utf8 = new UTF8Encoding();
var html = utf8.GetString(webClient.DownloadData(whatIsMyIpUrl));
var externalIp = IPAddress.Parse(html);
return externalIp;
}

The full solution can be downloaded from:
https://p2piter.blob.core.windows.net/theazureexperience/AzureFindMyLaptop.zip

You will need to enter your own information in the constants at the top of Program.cs:

private const string ServiceNamespace = "findmylaptopdemo";
private const string IssuerName = "owner";
private const string IssuerSecret = "XXXYYYZZZ";

Good luck!

Advertisements

One thought on “Publically exposing a service on my laptop using the AppFabric Service Bus

  1. Aw, this was an incredibly good post. Taking the
    time and actual effort to make a great article… but what can I
    say… I hesitate a whole lot and don’t manage to get nearly
    anything done.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s