In the previous post, we discussed that you can not only run some of your favorite technologies in Windows Azure but that you can easily cloud-enhance them with capabilities such as automation, elasticity, and diagnostics.

My recent post on the official Windows Azure blog introduces an example, describing how to run a client-server application (e.g. a relational database or distributed memory cache) in Windows Azure and then add elasticity to the server tier. Elasticity allows you to minimize your costs by dynamically adjusting capacity to meet demand. Let’s dig a bit deeper, diving into what the corresponding code would look like:

Service Definition

To get started, we need to define the server tier and declare an internal endpoint.

<WorkerRole name="MyServer" enableNativeCodeExecution="true">
    <!-- Defines an internal endpoint for inter-role communication that can be used to communicate between worker or Web role instances -->
    <InternalEndpoint name="MyEndpoint" protocol="tcp" />

Client Code

Note that only three lines of Windows Azure specific code, highlighted below, are needed to a) initialize the client and b) reinitialize the client when server instances are added or removed.

private MyClient InitializeClient() {
    var client = new MyClient();
    foreach (var inst in RoleEnvironment.Roles["MyServer"].Instances) {
        client.Add(inst.Id, inst.InstanceEndpoints["MyEndpoint"]);
    return client;

public void Go() {
    // Initialize the client
    var client = InitializeClient();

    // Reinitialize the client when there is a topology change
    RoleEnvironment.Changed += (sender, args) => {
        if (args.Changes.Any(chg => chg is RoleEnvironmentTopologyChange)) {
            client = InitializeClient();

    // Use the client as you would outside Windows Azure…

Server Code

Finally, we add one incremental line of code on the server tier, highlighted below, to discover the IP address and port to bind to.

// Discover the IP address and port assigned by Windows Azure
var ep = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["MyEndpoint"];

// Start the listener -- in this case another process -- passing in this info
var startInfo = new ProcessStartInfo
    FileName = @".\MyServer.exe",
    Arguments = "-l " + ep.Address + " -p " + ep.Port,
    UseShellExecute = false,
    CreateNoWindow = true