Friday, 3 May 2013

Backgammon with SignalR – Part Three – Client Side SignalR

This is the last of a three part series of posts on BackgammonR – an online Backgammon game built with SignalR. If you haven’t read it already, please see Part 1 – Game Engine and Part 2 – Server Side SignalR

The first bit of JavaScript to note is not actually something you write, rather what SignalR generates in order for it to allow for the messages to be passed between client and server and vice versa. It’s at /signalr/hubs/ and if you view it you’ll can see how the methods defined on the server-side hub are exposed to the client.

The script I have written though lives in /public/site/backgammon.js and whilst it consists of a number of methods it can be considered in three main sections.

Data Binding

Before getting into the client-side SignalR code it’s worth flagging up the other libraries I’ve used here. Jquery of course. But also knockout, which provides a nice separation between the intricacies of the UI and the details of the client-side model manipulated in code. It provides a means of automatically data-binding updates to the model – so for example when a new player is added the list displaying those users will be automatically refreshed.

This is all managed in the set of functions under the “Data Binding” comment. A client-side view model is set-up and maintained via helper methods to store details of what is displayed via the browser – i.e. the list of players, games and details of the selected game the user might be playing.

Persistent Connection

Beneath the “Persistent Connection” lies the SignalR related code, primarily in the initPersistentConnection() method. The first thing that occurs is a reference is stored to the SignalR hub:

    var hub = $.connection.gameNotificationHub;

You’ll see here the name of the hub is the same as that defined for the class on the server. The next lines of code define the client-side methods that are called from the server. Going back to the method described in the previous post form when a player joins, there were two client side notifications made – one to the caller and one to all users of the site. These two functions are wired up as below:

        hub.client.joined = function (player, connectionId) {
            addPlayer(player);
            if ($.connection.hub.id != connectionId) {
                notify(player.Name + " has joined.", "message", true);
            }
        };

        hub.client.callerJoined = function (name) {            
            viewModel.name(name);
        };

callerJoined is the one that is sent to just the caller – all we do here is update the view model to set the name and have knockout bind it to the UI. joined is a notification to all players, to update the list of players held on the view model. It also uses the connectionId that’s exposed client as well as server side to display a notification message to all players other than the caller.

The final lines of code in this function are held within the callback of the $.connection.hub.start().done() method. This is where some initialisation calls to the hub are made, and jquery is used to link up various events with the UI. For example against each available player in the list is a link to challenge them; when clicked the name of the player is pulled from the DOM and a SignalR call to the hub’s Challenge method is made.

            $(document).on("click", "#player-list a.challenge", function () {
                var challengedPlayer = $(this).prevAll("span.player-name").text();
                hub.server.challenge(challengedPlayer);
                return false;
            });

Game Canvas

The functions under the comment “Game canvas” are all involved with the drawing of the game board and counters. I decided to use HTML canvas for this as although it would likely have been feasible with pure CSS – and in fact would probably have been better should I want to introduce drag-drop of the pieces rather than the rather clunky form interface I have at the moment – it was again something I was keen to play around with.

Apart from the one function to draw the counters which was one of those write once and hope you don’t have to come back to it events, it’s mostly fairly straightforward. The idea is to get a reference to the canvas and then to the 2D context within it. Once that’s obtained the drawImage method is used to draw the board and the counters in the right places.

And that’s that... so far anyway. There’s still a bit to do – in particularly the end game and making the whole thing look a bit nicer. But that’s mostly details… as far as the SignalR parts are concerned that’s all in place and can say it’s been a fun little side project to work on.

Play the game

View the code

Backgammon with SignalR – Part Two – Server Side SignalR

This is the second of a three part series of posts on BackgammonR – an online Backgammon game built with SignalR. If you haven’t read it already, please see Part 1 – Game Engine.

SignalR actually provides two abstractions above the base technologies for maintaining persistent connections between browser and server. One is fairly low-level, called PersistentConnection that I didn’t look into. The other is Hubs.

I have a single SignalR hub called GameNotificationHub which inherits from Microsoft.AspNet.SignalR.Hub and thus obtains its base functionality. Within that class you can create public methods, which – once SignalR has worked its magic – become end-points that can be called from the client-side JavaScript.

They all return void though – which initially seems counter-intuitive and not what you would do were you wiring up an end-point for an AJAX request for example. However the point is of course that with this type of application we may need to push responses to this method call not just to the caller, but also to groups of other users connected to the application as well.

This is done via the Clients property – which has various dynamic fields such as Caller, All, Others, Group to allow you to send messages to just the appropriate sets of users. Strung on the end of that are further dynamic methods that will resolve to client-side code that is “called” from the server. Parameters can be passed to these messages – which can be simple strings or more complex types that will be accessible as JSON on the client.

For example the code sample that follows illustrates the Join method on the hub. It’s called when an authenticated user first access the game. There’s a check to ensure that the user hasn’t already joined, and if not, they are added to the list of players. Two notifications to the client are made – one to the caller to trigger the update of their screen, and one to all users to flash a message that a new player has joined.

        public void Join(string name)
        {
            if (!Manager.Instance.Players.Any(x => x.Name == name))
            {
                var user = new Player 
                { 
                    Name = name, 
                    ConnectionId = Context.ConnectionId,
                    Status = ConnectionStatus.ReadyToPlay 
                };
                Manager.Instance.Players.Add(user);

                Clients.All.joined(user, Context.ConnectionId);
                Clients.Caller.callerJoined(name);                
            }
        }

Other methods on the hub allow users to leave, challenge others to games, accept or reject those challenges and to take turns in the game.

The groups feature was particularly useful here. Within SignalR you can create groups as you see fit and assign users to them, and so push messages to just particular groups of them. The classic example of this is the rooms in a chat site. I used a group for each game, identifying it by the game Id, and thus only pushing updates to those users playing or viewing a game. For example in the Move method parameters are passed identifying the game and the move requested. Checks are made to ensure it’s the calling user’s turn and that the move they want to make is valid according to the rules of the game. If that’s all OK, the internal state of the game is updated and the whole Game object passed as a notification to the group associated with that game.

        public void Move(Guid gameId, int[] from, int[] to)
        {
            var game = GetGame(gameId);
            if (game != null)
            {
                if ((game.CurrentPlayer == 1 && game.Black.ConnectionId == Context.ConnectionId) ||
                    (game.CurrentPlayer == 2 && game.White.ConnectionId == Context.ConnectionId))
                {
                    if (game.Move(from, to))
                    {
                        // Notify all clients in group of move
                        Clients.Group(game.Id.ToString()).moved(game);
                    }
                    else
                    {
                        Clients.Caller.displayError("Invalid move.");
                    }
                }
                else
                {
                    Clients.Caller.displayError("Not your turn.");
                }
            }
            else
            {
                Clients.Caller.displayError("Game not found.");
            }
        }

Click for Part 2 – SignalR on the client

Play the game

View the code

Backgammon with SignalR – Part One – Game Engine

There’s no doubt who the cool kid on the block is when it comes to the “one ASP.Net” stack – SignalR, a library created to simplify the process of creating responsive applications that push AND receive notifications from the server. It provides a wrapper around a range of technologies that can provide persistent or semi-persistent connections, choosing the best available when the full chain from browser to server is taken into account.

Wanting to look into this technology with a project that’s at least semi-real, I was inspired by an article in a recent edition of the digital magazine Dot Net Curry where the author created a game of noughts and crosses (or tick-tac-toe). Chess was going to be beyond me for sure, but I figured a game of Backgammon might be feasible to get running. Hence BackgammonR – for some reason all apps using the technology need to end with a capital R.

The application I’ve built so far so far is running here on Azure. And code should anyone want to look into it further is here on Github. Worth flagging from the outset that you certainly won’t play the best game of Backgammon of your life on the app... at least yet. But it’s definitely proved its worth in allowing me to get to grips with the technology.

I’ll explain the code a bit more in this and two further blog posts.

The Game Engine

I won’t actually mention SignalR further in this post though; instead will go through some of the features of the game engine itself.

The application is based on ASP.Net MVC 4 and consists of a single project, plus a project for some unit tests. The game engine I’ve set up in the Models directory and it consists of three key classes.

Manager is a class set up using a singleton pattern to maintain an application wide, static instance of a single object. It contains two lists – one of players and one of the games. As you’ll see there’s no backing store such as a database to persist this information which would be needed were this anywhere near a real application. Currently if the application restarts or the app pool recycles all the running games would be lost. But it’s a nice, quick and easy way to get some form of application state running.

    public class Manager
    {
        private static readonly Manager _instance = new Manager();

        private Manager()
        {
            Players = new List<Player>();
            Games = new List<Game>();
        }

        public static Manager Instance
        {
            get
            {
                return _instance;
            }
        }
        
        public List<Player> Players { get; set; }

        public List<Game> Games { get; set; }
    }

Player is a very simple POCO that holds properties of the player name, connection status and connection Id that’s used by SignalR to recognise each connection.

Game is where the core of the game engine logic is coded. It contains properties that describe a single instance of a game, for example which player is black and white, whose turn it is and with the state of the board and dice.

The last dice roll is modelled as a simple integer array with 2 elements – one for each die. And similarly the board – this is a two-dimensional integer array with one dimension containing an element for each player and the other dimension holding the number of counters for each point. I actually have 26 points – 24 for each of the points, with the first and last position used for the bar and pieces that have been beared off respectively.

As well as these properties are various public methods such as RollDice and Move, along with private ones for validating the moves are valid and updating the state of the board.

Unit Tests

The bulk – in fact currently all – of the unit tests have been written to design and test the Game class, as this is where the bulk of the back-end logic resides. When I’m working with unit tests I like to ensure I cover all classes and methods that are a) have some complexity to provide value for the tests b) not too hard to test in terms of tricky dependencies. I find that provides the most return on investment in testing effort.

This class falls squarely into that category – it has no dependencies so there is no need for mocking and it offered a nice way to work in a TDD fashion as I worked through the various rules for what makes a move valid or not. Here’s an example test:

        [TestMethod]
        public void Game_MoveMatchesDiceButToOccupiedPoint_IsInvalid()
        {
            // Arrange
            var player1 = new Player { Name = "Player 1", };
            var player2 = new Player { Name = "Player 2", };
            var game = new Game(player1, player2);
            game.Dice[0] = 2;
            game.Dice[1] = 5;

            // Act  
            var result = game.Move(new int[] { 1, 1 }, new int[] { 3, 6 });

            // Assert
            Assert.IsFalse(result);
            Assert.AreEqual(1, game.CurrentPlayer);
        }

Authentication

To authenticate users again I’ve used something very simple just to get this working and move onto more interesting aspects of the project. The application uses Forms Authentication via a simple custom membership provider called AppMembershipProvider that merely checks that the name of the player is unique.

        public override bool ValidateUser(string username, string password)
        {
            // All we care about for now is that user name is unique
            return !Manager.Instance.Players.Any(x => x.Name == username);
        }

The HomeController has methods for handling this flow before redirecting authenticated users to the Game method where the backgammon functionality lives.

Worth flagging an issue I ran into here – as did the author of this stack overflow post – which is that initially I looked to set up Forms Authentication from within the SignalR hub. This caused issues as the connection that SignalR recognised for each user was lost between the unauthenticated and authenticated states. So best to keep it separate.

Play the game

View the code

Monday, 18 March 2013

Facebook, Internet Explorer, Anti-Forgery Tokens and Cookies

Tricky issue with the above 4 in one app...

IE was blocking a session cookie from my ASP.Net MVC web application when hosted in the Facebook IFRAME. The anti-forgery token in ASP.Net (used to protected against spoof form posts known as CSRF attacks) would fail saying the cookie it was checking against couldn't be found.

Turns out the issue was that in medium security settings, IE will "block third-party cookies that do not have a compact privacy policy". And as the app is in the IFRAME it is considered third party with respect to Facebook.

To resolve I needed two things:

1) an XML file located at /w3c/p3p.xml containing

<META xmlns="http://www.w3.org/2002/01/P3Pv1">
  <POLICY-REFERENCES>
    <EXPIRY max-age="10000000"/>
  </POLICY-REFERENCES>
</META>

2) and a header emitted (in server side code, the meta tag equivalent didn't seem to suffice)

Response.AppendHeader("P3P", "CP='IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA'");

At some point should really make sure that the file and header actually reflect what the privacy policy is... but for the issue at hand just having the header and XML present suffices. If you then go View > Website Privacy Policy... you should find the cookies are no longer blocked.

Friday, 8 March 2013

Localised Form Validation in ASP.Net MVC

I've recently been working on a web application that required localisation - the display of translated copy depending on which country the user was visiting from. There was a different sub-domain for each country which was used to identify the appropriate one.

It was also a requirement that the editor's of the website could update the translated copy from a simple back-office tool.

For most of the copy of the website this was fairly straightforward to set up. I had a database table called Texts that contained three columns: Country, Key and Value. And hence by looking up for a particular country and key I could get the text to display.

To ensure this was performant in practice what I did for each web request was to look up all the keys and values for the appropriate market and populate a dictionary object. The look-up was cached using so I was only hitting the database when I needed to rather than on every request.

I then created a base view model that all other view models were derived from that looked like this:

    public abstract class BaseViewModel
    {
        public BaseViewModel(IList<Text> dictionary)
        {
            Dictionary = dictionary;
        }

        public IList<Text> Dictionary { get; set; }

        public string GetText(string key)
        {
            if (Dictionary != null && !string.IsNullOrEmpty(key))
            {
                var text = Dictionary.Where(x => x.Key == key).SingleOrDefault();
                if (text != null)
                {
                    return text.Value;
                }
            }

            return string.Empty;
        }
    }

With this in place, rendering the appropriate text from the view was a simple matter of calling the GetText method and passing the required key:

    @Model.GetText("copyright")

All very straightforward so far, but the piece that needed a bit more thought was how to handle form validation messages, supporting both client and server side methods. There's a fairly well established method using resource files, but in my case that wasn't ideal as I wanted to support the editor's making amends to the texts, and hence needed to have them in the database rather than baked into a resource.

First step was to apply the usual data annotations, but rather than hard coding the error messages I instead used the keys from my translations table, e.g.

    [Required(ErrorMessage = "contact_validation_first_name_required")]
    [StringLength(20, ErrorMessage = "contact_validation_first_name_length")]
    public string FirstName { get; set; }

In my view I set up the field as follows:

    
    @Html.EditorFor(m => m.FirstName)
    @Html.LocalizedValidationMessageFor(m => m.FirstName, Model.Dictionary)

LocalizedValidationMessageFor was a custom helper used to render the appropriate error message for the country, and was implemented as an extension method on the HtmlHelper:

    public static class LocalizationHelpers
    {
        public static MvcHtmlString LocalizedValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IList<Text> dictionary)
        {
            // Get HTML returned from base ValidationMessageFor method
            var html = ValidationExtensions.ValidationMessageFor(htmlHelper, expression);

            // Check we are looking at one that is flagging a validation error
            if (html != null && dictionary != null && html.ToString().Contains("field-validation-error"))
            {

                // Get the key from the HTML (it contains a single span tag)
                var key = html.Substring(html.IndexOf(">") + 1).Replace("</span>", string.Empty);

  // Look up the text value based on the key from the passed dictionary
                var text = dictionary.Where(x => x.Key == key).SingleOrDefault();
                if (text != null)
                {

          // Replace the key with the translation
                    var amendedHtml = html.ToString().Replace(key, text.Value);
                    return MvcHtmlString.Create(amendedHtml);
                }
            }

            return html;            
        }
    }

That worked nicely for server side validation messages, but the client side ones would still display the key rather than the translated text. To handle this scenario I added a further method the BaseViewModel which would return the part of the dictionary of key/value pairs as a JSON result:

    public string GetDictionaryAsJson(string stem = "")
    {
        if (Dictionary != null)
        {
            var serializer = new JavaScriptSerializer();
            return serializer.Serialize(Dictionary
                .Where(x => string.IsNullOrEmpty(stem) || x.Key.StartsWith(stem))
                .Select(x => new { Key = x.Key, Value = x.Value }));
        }

        return string.Empty;
    }

From within the view, I made a call to a javascript function, passing in this dictionary in JSON format:

    localizeClientSideValidationMessages(@Html.Raw(Model.GetDictionaryAsJson("contact_validation")));

That function looked like the following, where for each tye of validation I was using (required, string length etc.) the key that was currently rendered was replaced with the appropriate translated text retrieved from the dictionary:

    function localizeClientSideValidationMessages(dictionary) {

        // Convert to JSON arry
        dictionary = eval(dictionary);

        // Localize fields (need to call for each type of validation)
        localizeFieldValidation(dictionary, "data-val-required");
        localizeFieldValidation(dictionary, "data-val-length");
        localizeFieldValidation(dictionary, "data-val-regex");
        localizeFieldValidation(dictionary, "data-val-equalto");

        // Reparse form (necessary to ensure updates)
        $("form").removeData("validator");
        $("form").removeData("unobtrusiveValidation");
        $.validator.unobtrusive.parse("form");

    }

    function localizeFieldValidation(dictionary, validationAttribute) {
       
        // For each form element with validation attribute, replace the key with the translated text
        $("input[" + validationAttribute + "],select[" + validationAttribute + "],textarea[" + validationAttribute + "]").each(function (index) {
            $(this).attr(validationAttribute, getLocalizedValue(dictionary, $(this).attr(validationAttribute)));
        });

    }

    function getLocalizedValue(dictionary, key) {

 // Look up the value for the passed key
        for (var item in dictionary) {
            if (dictionary.hasOwnProperty(item)) {
                if (dictionary[item].Key == key) {
                    return dictionary[item].Value;
                }
            }
        }

        return "";

    }

Sunday, 2 September 2012

Working with Stylecop

I was recently asked to review the use of Stylecop as part of our standard procedures for ASP.Net projects. I'd not used it before, but was fairly happy to consider doing so as code styling has always been one of my pedantic points when reviewing code (including my own!).

Have to admit I was less keen once I'd installed it and found it complaining with around several hundred warnings - on a single, not that complex, and - I'd thought - beautifully coded class library.

Having uninstalled it, calmed down a bit a couple of weeks later, reinstalled it, and put aside an afternoon to work through one particular solution... came to the conclusion it did have quite a lot of value.

Although no individual change was of any great significance, the code certainly felt better once the refactoring effort had been completed - and we'd expect over time that any best practices it enforced we weren't adhering too, would become normal coding style.

So our plan is to use it on any greenfield projects, and to incorporate it into legacy projects on a case by case basis.  The hope it it'll make working as teams of developers on a project easier and make picking up on a code base that someone hasn't worked on before more efficient.

Settings

Stylecop's settings if all left at the defaults are pretty strict... a bit too much so for my taste.  Whilst keeping most in place, these were the few I felt reasonable to remove for our working practices.

First I removed a number of documentation ones.  These fell into the category of agreeing with most of the time, but I didn't want it enforced 100% of the time.  Were we in the habit of generated hard-copy documentation from the XML comments, I would leave them in place, but as we aren't our comments are purely for those reading the source code.  In that case, I'd prefer comments were well-written and meaningful rather than completed purely for habit.  For example, if a method is short, well-defined and  sensibly named; it doesn't always need a comment.

Second to go was the requirement to list all methods in a class in accessibility order - i.e. all publics, then protected, then privates.  Personally I'd prefer a local, helper private method to be close to where it is called from a public one, to aid code-readability.

Lastly, after some debate, we retained the option of prefixing with _ to indicate private variables.  And related to this, didn't enforce the use of this to prefix local fields.

Some tips on refactoring

As mentioned, the plan is to use the tool mostly on greenfield projects.  However at times we'll want to fix-up existing projects to adhere to the agreed styles.  Having worked through a few now, these are the points I noted to at least slightly ease the pain.

  • Probably use Resharper.  I've not yet taken the time to install and learn this... but I probably should.
  • Without that though, there are couple of other VS.Net extensions that I have used and can help with this.  These are the Power Commands and the Productivity Tools.  I actually removed the latter as it seemed to noticeably slow down by IDE, but the Power Command's Remove and Sort Usings is worth it by itself.
  • Ctrl K + D will reformat code and fix some of the readability issues.  No more "invalid spacing around the closing curly brace".
  • The VS.Net menu Advanced > Untabify can be used to convert tabs to spaces on a file by file basis.
  • Find/replace of course can fix up some.
  • Lastly, when manually refactoring, I found it useful to order the list of warnings by file, and then within a file work from the bottom to the top.  That way the line numbers remain correct as you double-click on each issue.

Monday, 18 June 2012

Codegarden 2012 and Umbraco 5

Last week I attended Codegarden – the annual conference for the developers using the open source .Net CMS Umbraco held in Copenhagen. It’s probably fair to say that it’s not a typical technical conference. Rather more beer, bingo and unicyclists dressed as Darth Vadar playing the bagpipes than you might usually find.

Those aspects weren’t completely unexpected though. It was our first time at the conference but we’d had prior notice of the Danish take on Monty Python surrealist humour found during some of the “extra-curricular” sessions.

What was more of a surprise though was the announcement in the keynote – that they were scrapping development of the new version of Umbraco.

I have been following the progress of version 5 quite closely – working with it with colleagues in test projects and making some small contributions to its development. Although after its release a few months ago some issues were becoming apparent from reports of those using it; to take a call to abandon two years or so of development and go back to a prior version was a move that we certainly didn’t see coming.

Version 5 was intended as a clean slate development, utilising modern technologies and techniques including ASP.Net MVC. However the development style for Umbraco coders has never really followed this pattern. A lot more flexibility and logic is traditionally embedded in the templates (or in MVC parlance, the views) that in a more strict MVC implementation.

It seems that in trying to maintain this, yet removing the fast, in-memory XML cache used in version 4 lead to a lot of performance issues with data access once websites reached a certain size. This, coupled with the heavy use of abstractions leading to a complex code base and what is perceived as an over-engineered solution, seem to be the main reasons for its demise.

Initially this argument for the over complexity of the code seemed a little odd to me, given the architecture of version 5 was previously considered by most to be one of its strengths. The case that it was too much a “software engineers” solution didn’t seem to be a huge issue – we should probably expect that the development of the core of Umbraco may be accessible only to the more hard-core developers amongst us. But given other members of the core team who have had months or years working with it were admitting to struggling with it, you have to respect this recommendation to re-evaluate; and to ensure the development of Umbraco itself will be something more people can contribute to.

Luckily, whilst at work we have a number of Umbraco related projects in the pipeline, they all started either too early for us to consider use of V5, or late enough that we could get notice of the issues others were finding in practice. So for any client projects, we took a decision to stick for now with the tried and tested prior version, and that has turned out to be the right move.

Others may be in more unfortunate positions though of course having made greater investments in working with the new version of Umbraco. Whilst reaction at the conference seemed to be broadly disappointed but supportive, online the response was a lot more mixed.

Clearly this announcement cast a shadow over most of the rest of the conference. Most people had attended expecting to learn and discuss working with the new version of Umbraco, but obviously sessions planned on these topics were rather pointless now. Time was filled with talks on existing Umbraco techniques and more general web development topics – which were interesting and useful, but not really what we had come for.

The last day was given up to an “open space” – where the conference attendees and organisers divide into groups to discuss various suggested topics around Umbraco and its future. I felt this led to a much more optimistic closing to the conference than might have been anticipated after the first morning, and really demonstrated one of the core strengths of Umbraco – its committed community of developers.

Some discussions I participated in revolved around where to take development next, and others were looking at what can be salvaged from the work over the past year or so and still put to good use. The answer to this seems to be quite a lot, so it’s likely that a lot of learnings and specific features will still make their way into the product. Work is also planned to refactor some existing code and features that would have been refreshed by the clean slate approach now abandoned.

This roadmap for development, plus the spirit of participation engendered by the conference that I hope to continue to be involved with, suggests the future for Umbraco will still be bright (and orange).