wcfnettcpbindingwasazure-web-rolestcpportsharing

Hosting TCP based WCF service on the same ports as IIS (via Windows Activation Service) in Azure WebRole


How should one configure an Azure Webrole when using a TCP-based WCF on the same ports as IIS?

An on-premise solution would typically use WAS activation, however this usually involved setting permissions on the HTTP ports etc. In Windows Azure this interface isn't readily available.


Solution

  • The best way to host a WCF service in an Azure WebRole is using Windows Activation Service (WAS). Typically this is needed when you want to provide web content (HTTP) and some TCP-based WCF service on the same ports (80 or 443).

    Here is a PowerShell script that will enable the TCPPortSharing service, and configure IIS appropriately. Although this works for Azure, with slight modification you can use this for an on-premise Windows 2008 R2 server as well.

    #adding this to be sure that IISConfigurator has a chance complete
    
    Add-Content -path .\trace.txt "Starting...$([Datetime]::Now.ToString())" 
    
    Start-Sleep -s 300
    
    Add-Content -path .\trace.txt "Adding Microsoft.WindowsAzure.ServiceRuntime..."
    Add-PSSnapin Microsoft.WindowsAzure.ServiceRuntime
    while (!$?)
    {
        Add-Content -path .\trace.txt "Failed to add Microsoft.WindowsAzure.ServiceRuntime, retrying after five seconds..."
        sleep 5
    
        Add-PSSnapin Microsoft.WindowsAzure.ServiceRuntime
    }
    
    Add-Content -path .\trace.txt "...done adding Microsoft.WindowsAzure.ServiceRuntime $([Datetime]::Now.ToString())"
    
    #Start the Net.TCP Port Sharing and Net.Tcp Listener Adaptor services.. (TODO:Not sure if we need to set this to auto)
    
    Add-Content -path .\trace.txt "Setting NetTcpPortSharing & NetTcpActivator service startup to auto... $([Datetime]::Now.ToString())"
    
    Set-Service NetTcpPortSharing -StartupType Automatic
    Set-Service NetTcpActivator -StartupType Automatic
    
    Add-Content -path .\trace.txt "...done Setting NetTcpPortSharing & NetTcpActivator service startup to auto ... $([Datetime]::Now.ToString())"
    
    Add-Content -path .\trace.txt "Starting NetTcpPortSharing & NetTcpActivator services ... $([Datetime]::Now.ToString())"
    
    Start-Service -name NetTcpPortSharing
    Start-Service -name NetTcpActivator
    
    Add-Content -path .\trace.txt "... done Starting NetTcpPortSharing & NetTcpActivator services $([Datetime]::Now.ToString())"
    
    #Get the Role Instance Id
    
    Add-Content -path .\trace.txt "Getting the RoleInstance ID... $([Datetime]::Now.ToString())"
    
    $roleInstance = Get-RoleInstance -current
    $roleInstanceId = $roleInstance.Id
    
    $siteName = '_Web'  #This is the site name from the <Site> tag in ServiceDefinition.csdef
    
    Add-Content -path .\trace.txt "Instance ID : $roleInstanceId"
    
    Add-Content -path .\trace.txt "... done Getting the RoleInstance ID $([Datetime]::Now.ToString())"
    
    #Create the bindingCmd
    
    #Add-Content -path .\trace.txt "Building commands ..."
    
    #$addBindingCmd =  "set site `"" + $roleInstanceId + "_" + $siteName + "`" -+bindings.[protocol='net.tcp',bindingInformation='808:*']"
    #$enableNetTcpCmd =  "set app `"" + $roleInstanceId + "_" + $siteName + "`" /enabledProtocols:http,net.tcp"
    
    Add-Content -path .\trace.txt -value $addBindingCmd
    Add-Content -path .\trace.txt -value $enableNetTcpCmd
    Add-Content -path .\trace.txt -value "...done Building commands"
    
    set-alias appCmd $env:windir\system32\inetsrv\appcmd.exe
    
    Add-Content -path .\trace.txt -value "Adding Net.Tcp binding... $([Datetime]::Now.ToString())"
    
    #add the binding..
    #appCmd $addBindingCmd 
    
    appCmd set site `"$roleInstanceId$siteName`" /debug -+"bindings.[protocol='net.tcp',bindingInformation='808:*']" >>trace.txt
    
    Add-Content -path .\trace.txt -value "done Adding Net.Tcp binding"
    
    Add-Content -path .\trace.txt -value "Enable Net.Tcp... $([Datetime]::Now.ToString())"
    #appCmd $enableNetTcpCmd
    appCmd set app "$roleInstanceId$siteName/" /debug /enabledProtocols:"http,net.tcp" >> trace.txt
    Add-Content -path .\trace.txt -value "done Enable Net.Tcp"
    
    Add-Content -path .\trace.txt -value "End $([Datetime]::Now.ToString())"