Local machine connectivity from Windows Phone 8 Emulator

This has been documented before in MSDN and couple of other blogs; but I struggled for a few hours and went through several resources before figuring out what needed to be done as a solution. Just sharing my way of getting stuff to work ..

The Problem:
You are developing a Windows Phone 8 app using the emulator and want to consume/interact with a service/website on local development machine. The server side mimics the backend service powering your Windows Phone app; this could be in the form of a WCF Web Service or a Web API endpoint or in my case, a SignalR Hub for real-time connectivity. This seemingly simple task of connecting the Windows Phone emulator running the Phone app to the service/website on local machine actually turns out to be a tricky one.

The Cause:
Part of the problem lies in the Windows Phone emulator. In the old Windows Phone 7 days, the emulator used the network connection of the development computer; this meant reaching anything on ‘localhost’ was trivial. The Windows Phone 8 Emulator, however, configures itself as a separate device on the network. As a result, an app running on the Windows Phone 8 Emulator can’t connect to the development computer through ‘localhost’. In essence, when you say ‘localhost’ from the Windows Phone 8 app, you are actually referring to the ‘localhost’ of the Windows Phone 8 emulator Hyper-V Virtual machine, and not that of your development machine which is hosting the backend service. This is true if using the inbuilt Casini web server or IIS Express. You now have your local machine and the Windows Phone emulator as two different machines, refusing to talk to each other!

My Case:
As for where I got stuck – I have a simple Visual Studio solution with three projects.

  1. An MVC 3 Web Application which wraps several SignalR Hubs for real-time communication across web & mobile devices
  2. A Windows Phone 8 app which attempts to talk to the SignalR Hubs
  3. A Windows 8 Store app which does the same

The SignalR backend server uses the latest Microsoft.AspNET.SignalR bits and both the clients have the newest SignalR .NET client library NuGet packages. Granted the SignalR server has a Hub called ‘ChatHub’, here’s the kind of code you would expect to write from a .NET 4.5 client:


IHubProxy SignalRChatHub;
HubConnection chatConnection = new HubConnection("http://localhost:53478/");
SignalRChatHub = chatConnection.CreateHubProxy("ChatHub");

await chatConnection.Start();
if (chatConnection.State == Microsoft.AspNet.SignalR.Client.ConnectionState.Connected)
{
      await SignalRChatHub.Invoke("SomeMethodOnServer", "ExpectedParameters");
}

Well, the code above will connect a Windows Store app or for that matter any .NET 4.5 app to the SignalR backend server running on your ‘localhost’. The only exception is the Windows Phone emulator and for reasons we talked above. So, what’s the workaround?

The Solution:
Here are the series of steps I took:

  • Domain dis-join your development machine and turn off any VPN tunnel software. These use special IP Security protocols that the WP Emulator does not like.
  • Check the Windows Phone emulator virtual network switches. A simple ‘ipconfig’ will tell you what the HyperV VM is using for connections; it would most likely be like 169.254.nn.nn.
  • Next step is to configure IIS for external access. Normally, ‘localhost’ can only be hit from the same development machine; so you can see why the WP emulator cannot reach your IIS server. Shut down IIS Express, be brave & hand-edit some config. In your ‘C:\Users\\Documents\IISExpress\config’ folder, sits an ‘applicationhost.config’ file which IIS Express reads. Find your backend service application and tweak the config to allow access from a local IP address. Here’s what mine looks like:

    
    <bindings>
        <binding protocol="http" bindingInformation="*:53478:localhost" />
        <binding protocol="http" bindingInformation="169.254.80.80:53478:" />
    </bindings>
    

    You’ll notice that the local IP address binding I chose falls in the range of what the WP emulator VM would be using.

  • Now, open your service application through Visual Studio in Administrator mode; this is important since IIS will throw an access denied error otherwise. Fire up the backend service and make sure it is accessible from both ‘localhost’ and the specified IP address. This should work regardless of whether you have a website, SignalR Hub, WCF service or a Web API endpoint.
  • One more roadblock exists – even though we configured IIS Express to run our applications from an IP address in addition to ‘localhost’, it will still block requests from other devices on the network. To allow this needs a little tweak of Windows Firewall rules. I quote from MSDN to create a firewall exception for HTTP requests to IIS Express:
    1. From the Windows Start screen, search for Windows Firewall. Click to run the program.
    2. On the Windows Firewall screen, click Advanced settings.
    3. On the Windows Firewall with Advanced Security screen, select Inbound Rules. Then click New Rule.
    4. On the Rule Type page of the New Inbound Rule Wizard, select Port. Then click Next.
    5. On the Protocols and Ports page, enter the port number that IIS Express is using in the Specific local ports field. Then click Next.
    6. On the Action page, select Allow the connection. Then click Next.
    7. On the Profile page, select Private and, if applicable, Domain. Do not select Public. Then click Next.
    8. On the Name page, type a name for the rule. Then click Finish.
  • Now, you should be all set. Fire up the WP emulator and navigate to your website in IE through the IP – should be able to access it. If using a WCF Service or Web API endpoint, make sure to Add Reference using the specified IP address that was allowed in IIS Express. As for my SignalR Hub connectivity from Windows Phone emulator, here’s the code that works:

    
    IHubProxy SignalRMapHub;
    HubConnection mapConnection = new HubConnection("http://169.254.80.80:53478");
    SignalRMapHub = mapConnection.CreateHubProxy("MapHub");
    
    public async virtual void MapIt(MapClient phoneToMap)
            {
                // Fire up SignalR Connection & share location.  
                try
                {
                    await mapConnection.Start();
    
                    if (mapConnection.State == Microsoft.AspNet.SignalR.Client.ConnectionState.Connected)
                    {
                        await SignalRMapHub.Invoke("ShowClientOnMap", phoneToMap);
                    }
                }
                catch (Exception)
                {
                    // Do some error handling.
                }
            }
    

So, there you have it – seamless connectivity to local development machine websites/services from the Windows Phone emulator. Do not forget to switch things to hosted settings once you are satisfied with local testing and ready to push stuff out to production.

Hope this was helpful. Adios!

4 thoughts on “Local machine connectivity from Windows Phone 8 Emulator

Leave a reply to www.allvoices.com Cancel reply