El pasado viernes 14 de marzo estuvimos hablando, vía hangout, Juan Quijano y un servidor sobre SignalR y Web API. A nosotros se unieron también Jorge Serrano, Gorka Madariaga, Luis Fraile y David Salgado entre otros, y otros tantos que nos observaron a través de Youtube.
Test it live: Realpoll at Azure
After my fist side-project (which I might publish on march or april) with Angular.js, I’ve been playing with different web technologies by doing a remake of a hackathon idea: Meet realpoll.
Teachers and speakers often need a way to engage the audience and give them the possibility to participate in the talk or the subject. Today is very common to see students tweeting from class, so this means they do have portable, wireless internet. The response of some centers is to block communications, but, why not use it the other way?
This web app allows the teachers to previously prepare some questions, choose the number of answers, the correct ones, and display the question on a projector. The students can then, use the url or capture the QR code generated from their cell phones. Once the question is generated, the trainer can choose the time that will be the poll open (in seconds).
When the time is up, the dashboard will mark the correct answers and those who answered correctly. The only data that is saved is the question and the answers, so you can come back and repeat it.
The voting interface is very, very simple: Just add a name and click on your chosen answer. It will be send inmediately to the dashboard.
Remake of a classic
The fact is that realpoll is a previous project done in a hackathon using a completely different tooling:
- redis for the data layer
- socket.io for handling the real time interaction
- express.js for handling routing and views
- google charts for the graphics
- plain jquery for DOM management
- Heroku as cloud host
- developed with VIM
For this project, I wanted to keep the idea, but change completely the technologies used:
- sql + entity framework for the data layer
- signalr for the real-time interaction
- ASP.net MVC for handling routing and views
- Chart.js for the graphics
- jquery and Angular.js for handling the views
- RazorEngine for the views
- Git/github as SCM
- Windows Azure as cloud host (connected to github)
- Visual Studio + IE dev tools + Chrome dev tools (+ Safari dev tools on mac)
- Sendgrid for mailing.
The backend is pure ASP.net MVC with the data stored in a SQL Server database, and some services (such as email) for making my life a little bit easier.
The system uses the database for storing the questions, so we can access later from a single URL. The URL is a hash based on the question ID. The voting process is not stored, so it resets when we refresh the dashboard. The communication between the database and the app is done by using Entity Framework, Microsoft’s open source ORM.
For being able to use data without having to worry about the ORM, I used dependency injection techniques to inject a fake data source. The Depencency Injection framework chosen was ninject, and while I had to create two different classes for ASP.net MVC and SignalR dependency solvers, I had a single entry point to replace the fake access with the ORM data source.
The “New” page looks like this, It’s bootstrap for the UI and angular for handling the UI updates when the question number changes:
When we create a question, data is updated in the database and we see a confirmation page like this:
For generating the e-mail sent I use RazorParser, a nuget-available dll that allows me to generate an html view from a model and a file, and once generated use it as a string. The e-mail is sent through sendgrid’s SMTP, using the standard SMTP functions.
The result page is one of the most complicated, the charts are created by using chart.js with a wrapper for angular, the qr code is generated by using the qrickit API, and it’s updated in real time by using signalR and angular.js for handling the views.
When the time is up, the correct solution is highlighted, and those whose answer matches are highlighted also
As Bootstrap is mobile ready, I had to do few changes to make the ui work flawlessly, had to do some debugging on Safari for Mac (whose web developer tools are way less powerul than Chrome/IE’s) connected to an iPhone. The cookie consent also adapts so, no issues here.
Stats and cookies
As the goal of the project was to play with technology, I havne’t been playing troo much with stats, but I did have added a google analytics code in each page. Also as I’m on the EU, there is a strict control of which cookies can be installed in the user’s machine (even more strict in Spain) so I’ve used the cookie consent code that allows the user to control the analytics tracking.
Source control, deploy and debug.
The project has been done by using git as source control manager, github as repository and the deployment has been done in Windows Azure. Azure has a hook for git, so when I push to github it will deploy to azure. As is git-based, it allows me to rollback inmediately while keeping the continuous deployment options available.
Finally, for remote debugging I added Elmah (Error Logging Modules and Handlers) to track down exceptions and issues that happened in Azure.
Issues, curious and weird things
- There is a bug with angular an Visual Studio’s browser link that causes constant debugger stops on frontend code, be aware.
- For adding dependency injection with ninject for signalR and MVC, you need to define two different dependency solvers, because they belong to different assemblies and implement different interfaces.
- Validating input data has become way easier with HTML5, butS afari (and specially safari for iPhone) do not support the required tag for html, a useful guide is caniuse
- For debugging on Safari for iPhone you need Safari running on Mac OS X.
- When you re-deploy a solution to azure, (with the configuration by default) you lose all the exceptions tracked by elmah
- I’ve used some funny xml transformations for handling local, remote and fake databases.
Room for improvement
Of course, there are always things that may go better, I didn’t write a single line of test code (other than my fake db wrapper) so it should be considered fairly unstable. The goal of this mini-project was to integrate as many technologies as possible to create a ready-to-deploy real-time web application. I would have added some UI tests with selenium, and maybe some unit testing for both angular and mvc controller.
You can test it live on Realpoll at Azure or you can get the source code from the project’s github repository and deploy it by yourself. You will need your own API keys and your own database for making it work. Comments will also be apreciated, and if you want to contribute back, just send a pull request!