Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.

  • Create BookmarkCreate Bookmark
  • Create Note or TagCreate Note or Tag
  • PrintPrint

Going Mobile

Adding support for mobile devices that also interact with SignalR is pretty easy now that we have the basics built. In this section I’ll show a few different approaches for extending the simple survey application to mobile devices. The first uses jQuery Mobile. The second is a native Windows Phone 7 application.

The jQuery Mobile Approach

I’ve shown several examples throughout this book that use jQuery Mobile and I mentioned briefly how you can quickly configure ASP.NET MVC 4 to react differently for different devices. However, I haven’t actually shown an example of this in action. Since we already have a web version of the survey application in place, this is a perfect opportunity to quickly walk through what is needed to switch out the views in an ASP.NET MVC 4 web application when a page is accessed by a mobile device.

You first need to add a new _Layout.cshtml file named _Layout.mobile.cshtml. The typical jQuery Mobile references are then added to this new _Layout file along with the same SignalR, D3, and mainModule JavaScript references that were included in the original _Layout file.

All we need to do now is to make a few adjustments to the HTML in the existing Index.cshtml file. With these changes, the one Index.cshtml file can be reused for both views. The markup, with changes emphasized, is as follows:

<div id="survey" class="page" data-role="page" >
  <div class="row" data-role="content">
    <form class="well"> 
      <fieldset data-role="controlgroup">
        <legend>What is your favorite programming language?</legend>
        <div class="controls">
          <label class="radio">
            <input type="radio" name="langOption" id="fsharp" value="F#" />F#
          </label>
          <label class="radio">
            <input type="radio" name="langOption" id="csharp" value="C#" />C#
          </label>
          <label class="radio">
            <input type="radio" name="langOption" id="erlang" value="Erlang" />
            Erlang
          </label>
          <label class="radio">
            <input type="radio" name="langOption" id="javascript"
              value="JavaScript" />
            JavaScript
          </label>
          <label class="radio">
            <input type="radio" name="langOption" id="other" value="Other" />
              Other
          </label>
        </div>
      </fieldset>
      <div class="buttonContainer"><button id="vote" class="btn" />
        Cast Vote</div>
    </form>
  </div>
</div>

<div id="results" class="page" data-role="page" >
  <div id="barChart" class="barChart" data-role="content" >
  </div>
</div>

Note

Instead of using the same Index.cshtml for both views, we could have created a new ASP.NET MVC view named Index.mobile.cshtml to house mobile-specific markup. This is a workable approach if we need to have completely different markup for specific device types; however, I believe it is best to try to keep the markup the same for both views and use media types and other adaptive and/or responsive design techniques to tailor the experience appropriately.

We can verify that things are working by switching out the user agent in a browser such as Chrome. Additionally, we can use emulators and/or simulators such as TestiPhone to see how things will look when displayed on screens of different sizes. The new look with an iPhone 5 user agent on a simulator is shown in Figure 4-3.

Adding Windows Phone

While the jQuery Mobile approach will work for all the major mobile players, we may wish to develop specific native apps that also take advantage of SignalR. As an example, perhaps we wish to take our simple survey application and create a native Windows Phone 7 version. The resultant visual aspects of the app are shown in Figure 4-4.

jQuery Mobile survey

Figure 4-3. jQuery Mobile survey

Windows Phone 7 survey

Figure 4-4. Windows Phone 7 survey

A deep dive into how to create Windows Phone 7 applications in F# could easily fill another book. However, you don’t need to read a whole other book to quickly get a simple Windows Phone 7 app with F# up and running. Simply install the Windows Phone SDK, then install one of the F# and C# Windows Phone project templates from Visual Studio Gallery, such as the one here.

I won’t spend a lot of time going into the details of the non-SignalR aspects of this example. You can find the full source at the GitHub website. One other thing to point out is that this example uses a self-hosted, persistent connection SignalR server. The code for this is available here.

Note

At the time of this writing, the Windows Phone 7 development tools are not yet supported in Visual Studio 2012. Because of this, the example provided in this section uses Visual Studio 2010.

After creating a new F# Windows Phone 7 project, we can add the desired XAML to make things appear as shown in Figure 4-4. Next, we need to install the SignalR.Client NuGet package in both the App and AppHost projects. We’re now ready to modify the AppLogic.fs file so that it interacts with the SignalR server.

To get started, we’ll first create a record that will act as a Model as well as a class to act as a ViewModel. To keep things simple, I’ve hardcoded the language choices and associated box color. Each of these is shown in the following example:

type LanguageChoice = { Language : string; BoxColor : string } 
    
type LanguageChoiceViewModel() =   
    member x.LanguageChoices = 
        let result = List<LanguageChoice>()
        result.Add { Language = "F#"; BoxColor = "#F29925" }
        result.Add { Language = "C#"; BoxColor = "#5492CD" }
        result.Add { Language = "Erlang"; BoxColor = "#E41F26" }
        result.Add { Language = "JavaScript"; BoxColor = "#70BE46" }
        result.Add { Language = "Other"; BoxColor = "#535353" }
        result

Note

Model-View-ViewModel (MVVM) is a common design pattern that is often used when building XAML-based solutions. You can find more information about MVVM on John Gossman’s blog. It should be noted that the example provided in this section does not follow MVVM fully. Instead, the example is optimized for simplicity and set up to show different approaches.

Now that the Model and ViewModel are created, we can modify the MainPage class to include the logic needed to send the selected vote information to the SignalR server. The code to accomplish this is shown in the next example and I’ll point out various interesting aspects in the next several paragraphs:

type MainPage() as this =
    inherit PhoneApplicationPage()
    do this.DataContext <- LanguageChoiceViewModel()
    do Application.LoadComponent(this, 
        new System.Uri("/WindowsPhoneApp;component/MainPage.xaml", 
            System.UriKind.Relative))

    let confirmationLabel : TextBlock = this?Confirmation

    member this.AnswerButton_Click(sender:obj, e:RoutedEventArgs) =
        let answerButton = sender :?> Button
        SignalR.connection.Send(answerButton.Tag)
            .Start(TaskScheduler.FromCurrentSynchronizationContext())
        confirmationLabel.Text <- "Thanks for Voting!"

The first few lines of code in this class are wiring up the class to the XAML. The class inherits PhoneApplicationPage, sets our ViewModel as the DataContext, and finally associates MainPage.xaml to the class.

The next line locates the TextBlock with a name of Confirmation in the XAML and binds it to a value named confirmationLabel. This shows a little bit of the power of the dynamic lookup operator that I talked about previously in this chapter. In the default output of this Windows Phone 7 project template, an implementation of the dynamic lookup operator is provided with the primary goal of locating resources in a ResourceDictionary or finding controls in XAML.

The AnswerButton_Click member shows a traditional code-behind type of click event handler. This is where we see the first mention of anything related to SignalR. Within this event handler, we determine which button was pressed and send the information to the SignalR server by starting the task from the current synchronization context. Lastly, the text of a label is set to a desired confirmation message.

The only other thing to discuss is how the SignalR server connection information is determined. In this example, this is accomplished by defining a module with a function named startConnection. This function is called whenever the application launches. Conversely, the connection is stopped whenever the application is closed. Here is the code for defining the module with the startConnection function:

module SignalR =
    let connection = 
        Connection "http://localhost:8081/chartserver"
    let startConnection() =
        if connection.State = ConnectionState.Disconnected then 
            connection.Start().Start(
                TaskScheduler.FromCurrentSynchronizationContext())
  • Safari Books Online
  • Create BookmarkCreate Bookmark
  • Create Note or TagCreate Note or Tag
  • PrintPrint