DCSIMG
December 2012 - Posts - Ran Wahle's blog

Ran Wahle's blog

December 2012 - Posts

Using SignalR with .Net client

Using SignalR with .Net client

 

In my previous post I demonstrated how to use SignalR with javascript client.
After this post, I got an email from my extremely talented colleague SignalR logo
Bnaya Eshet  asking if there’s a way to to SignalR with .Net client.
I said “yes” of course so now I want to demonstrate how to do it.
The server side code is the same as in my previous post, this is just
another client example.

 

Step 1: Create .Net client project:

Add some .Net project, any project type will do, I will demonstrate with 
a WPF project works with MVVM. The code samples will be from the
View-Model.

Step 2: Install SignalR .Net client nuget package

On the project you’ve just created, install Microsoft.AspNet.SignalR.Client
package.Make sure that both server project described in previous post has
the same version. If you didn’t, you will get an error of 
incompatible protocol version“ while trying to connect.

Step 3: Create SignalR connection instance

Using the namespace of Microsoft.AspNet.SignalR.Client.Hubs on
Microsoft.AspNet.SignalR.Client assembly (referenced to your project after
NuGet package installation) has a HubConnection class. This class used for
keeping persistent connection.

That’s how you create an instance of this class:

_connection = new HubConnection("http://localhost/RanWahle.Blog.SignalR.Demo");
           //useDefaultUrl = true

Where the first parameter is the site address, and the second  parameter
named useDefaultUrl tells you whether to use the default hubs URL or not.
You should set this parameter according to the way your hubs are registered
on your server.
The default value for that parameter is true, you need this one only if
the hubs aren’t registered at the default URL (thanks @davidfowl)

 

 

Step 4: Create proxy hub

Another component you can work with is the hub proxy component.
This componentis created by the connection in previous step, using its
CreateHubProxy method. This method returns an IHubProxy interface.
by default it will create a HubProxy class that implements it.

That’s how hub creation looks like:

IHubProxy proxy = connection.CreateHubProxy("soccerResultsHub");

 

Step 5: Handle server messages

The proxy created on previous step now needs to handle server messages. as seen in
my previous post The server calls Client.All.someMethod  pseudo method where
someMethod is actually a message that is sent to the clients. There are several
extension method of the IHubProxy interface, the recommended on is the On method
which accepts the event name as string, and the arguments as a collection of parameters.

This is how it looks like:

proxy.On<string, string>("updateTeams", (homeTeam, visitorTeam) =>
                      {
                          HomeTeamName = homeTeam;
                          VisitorsTeamName = visitorTeam;
                      });

We’ve used here two strings as a type parameters because the server sends two strings to the client
Here’s the corresponding server code.

Clients.All.updateTeams(_game.HomeTeam, _game.VisitorsTeam);

 

Step 6: Invoke server methods

In here, we use another IHubProxy method (a non extension one this time) called Invoke.
This method accepts the server side method as a string and a collection of parameters.

This is how it looks like:

proxy.Invoke("UpdateHomeTeamName", HomeTeamName)

Where the corresponding server method named UpdateHomeTeamName and accepts
one string as a parameter.

 

Summary

SignalR has a library for .Net client as well as javascript clients. If you are a .Net client
programmer you can also interact with the server suing SignalR . The steps above
demonstrate how you can do this very easily.

The full code example can be found here 

Enjoy, I’m sure you will.

kick it on DotNetKicks.com

Getting started with SignalR

Getting started with SignalR

 

Recently I’ve begun testing ASP.NET.SignalR, an open source project that supports real-time web functionality in our application.SignalR logo

SignalR can be added to an existing ASP.NET application and help as easily gain real-time functionality
in no-time. It can run with browsers that supports HTML5 WebSocket or long polling (IE 8).

 

SignalR has both server and client code, its client code is based on jQuery

In this post I’ll demonstrate how to work with SignalR along with a few basic terms related to it.

 

Install SignalR nuget package

First, you should install Microsoft.ASP.NET.SignalR nugget package, you can do so either by running install command on
nuget management console, or do so by searching the package on the nugget packages GUI.  It will install another 4 SignalR
related packages along with jQuery and JSON.Net packages which SignalR packages depends on.

 

Server Side Code

Now, what we need to do is to have some code that  will act as our service, in SignalR terms it is called Hub.
Our hub will be named SoccerResultsHub and will enable to update the home and visitor team, increment score
for each and update the time left.

For some separation of concern (even a demo needs it) here’s a class to manage hold game data

public class SoccerGame
   {
       private Timer _timer;
 
       public event EventHandler UpdateTimeLeft;
       public SoccerGame()
       {
           TimeLeft = 90;
           _timer = new Timer();
           _timer.Elapsed += (sender, args) =>
               {
                   TimeLeft--;
                   if (UpdateTimeLeft != null)
                       UpdateTimeLeft(this, null);
 
               };
           _timer.Interval = 60000;
           _timer.Start();
       }
       public string HomeTeam { get; set; }
 
       public string VisitorsTeam { get; set; }
 
       public int HomeScore { get; set; }
 
       public int VisitorScore { get; set; }
 
       public int TimeLeft { get; set; }
   }

This class will be used in our hub that looks like that:

public class SoccerResultsHub : Hub
  {
      private SoccerGame _game = new SoccerGame();
 
      public SoccerResultsHub()
      {
          _game.UpdateTimeLeft += (sender, args) => UpdateTimeLeft();
      }
 
      public void UpdateHomeTeamName(string teamName)
      {
          _game.HomeTeam = teamName;
          Clients.All.updateTeams(_game.HomeTeam, _game.VisitorsTeam);
      }
 
      public void UpdateVisitorTeamName(string teamName)
      {
          _game.VisitorsTeam = teamName;
          Clients.All.updateTeams(_game.HomeTeam, _game.VisitorsTeam);
      }
 
      public void UpdateTimeLeft()
      {
          Clients.All.updateTimeLeft(_game.TimeLeft);
      }
 
      public void ScoreForHome()
      {
          _game.HomeScore++;
          Clients.All.updateScores(_game.HomeScore, _game.VisitorScore);
      }
 
      public void ScoreForVisitors()
      {
          _game.VisitorScore++;
      }
 
 
  }
}

For each method on our Hub class, SignalR will create corresponding javascript code enables us to invoke from our client side.

Note the Clients.All.<method> , Clients property of Hub class has the connection context, and its type is self explanatory ConnectionContext .

It has several dynamic properties of which we can add method calls to, the SignalR engine will support extending its javascript ,  the All property of Clients

 

Client Side Code

On our HTML document we need to reference jQuery , SignalR base javascript library and the javascript proxy code generated by SignalR for our Hub above.

<script type="text/javascript" src="Scripts/jquery-1.6.4.js"></script>
  
 <script type="text/javascript" src="Scripts/jquery.signalR-1.0.0-alpha2.js">
</script>
 <script type="text/javascript" src="SignalR/Hubs">
</script>

We’d also use knockoutJs and that’s how our entire Html will look like:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <label for="txtHomeName">Home Team:</label>
    <input type="text" id="txtHomeName" data-bind="{value : homeTeamName}" />
    <button data-bind="{click: updateHomeTeamName}">Update</button>
    <button data-bind="{click: homeTeamScores}">Scores</button>
    <span data-bind="{text : homeTeamScore}"></span>
    <br />
     <label for="txtvisitorName">visitor Team:</label>
    <input type="text" id="txtvisitorName" data-bind="{value : visitorTeamName}" />
     <button data-bind="{click: updateVisitorTeamName}">Update</button>
    <button data-bind="{click: visitorTeamScores}">Scores</button>
    <span data-bind="{text : visitorTeamScore}"></span>
    <br />
    <span>Time Left:</span>
    <span data-bind="{text : timeLeft}"></span>
    <script type="text/javascript" src="Scripts/knockout-2.2.0.js"></script>
     
      <script type="text/javascript" src="Scripts/jquery-1.6.4.js">
    </script>
   <script type="text/javascript" src="Scripts/jquery.signalR-1.0.0-alpha2.js">
   </script>
       <script type="text/javascript" src="SignalR/Hubs">
    </script>
       <script type="text/javascript" src="GameViewModel.js">
</script>
</body>
</html>

 

Using knockoutJs  lets us have our client code deals with the data itself and doesn’t involve any DOM manipulation

In our javascript code we declare a view-model and inside it declare a member named gameHub. This member will be declared as the Hub connection
to the server. it will use to start the connection, call server methods and extend the client so the server can call functions on it (it is bi-directional right?)

You can see that gameHub member has client and server  members used for both purposes mentioned above

That’s how our javascript code will look like:

 
var viewModel =
    {
        gameHub : null,
        homeTeamName: ko.observable(),
        homeTeamScore: ko.observable(),
        visitorTeamName: ko.observable(),
        visitorTeamScore: ko.observable(),
        timeLeft: ko.observable(),
        homeTeamScores : function()
        {
            this.gameHub.server.scoreForHome();
        },
        visitorTeamScores: function () {
            this.gameHub.server.scoreForVisitors();
        },
        updateScores: function (home, visitors) {
            this.homeTeamScore(home);
            this.visitorTeamScore(visitors);
        },
            updateHomeTeamName : function()
            {
                this.gameHub.server.updateHomeTeamName(this.homeTeamName());
            },
            updateVisitorTeamName: function () {
                this.gameHub.server.updateVisitorTeamName(this.visitorTeamName());
            }
    };
 
$(document).ready(function () {
    
    ko.applyBindings(viewModel);
 
    viewModel.gameHub = $.connection.soccerResultsHub;
    viewModel.gameHub.connection.start();
 
    $.extend(viewModel.gameHub.client,
        {
            updateTimeLeft: function (timeLeft) {
                viewModel.timeLeft(timeLeft);
            },
            updateTeams: function (home, visitors) {
                viewModel.homeTeamName(home);
                viewModel.visitorTeamName(visitors);
            },
            updateScores: function (home, visitors) {
                viewModel.updateScores(home, visitors);
            }
        });
});

 

Summary

SignalR let’s us have bi-directional communication between the client and server. It runs on browsers that support websockets and long-polling

while signalR knows which of those features to use. It depends on jQuery on client side and Newtonsoft.Json (and ASP.NET) on server side.

It is still in alpha stage but sure worth a try,  knowing how to use it will help you create great Http based applications.

 

The entire sample can be downloaded here.

kick it on DotNetKicks.com

ASP.NET MVC 4 practice lab files

ASP.NET MVC 4 Lab files

 

Sela Developers Practice is over. I’ve had a great time speaking about jQuery
in a tutorial day about javascript with Gil Fink and Elad Katz, and on ASP.NET MVC 4
in a tutorial day again with Gil and Sebastian Pederiva, .

 

Demos from our MVC4 lecture can be found on Sebastian’s SkyDrive here, and some
hands-on labs can be found on my SkyDrive here.

I wish to thank all attendees and hope to see you all again on SDP13.