2013-08-31

Full day Microsoft awareness workshop at Wayamba University of Sri Lanka

We have conducted a full day workshop for the students and lecturers at Wayamba University of Sri Lanka on 14th of August, 2013. There were DPE lead of Sri Lanka Microsoft – Wellington Perera, 3 Sri Lankan MVPs (Hasitha, Preethiviraj and myself) and two Microsoft student ambassadors.

My part was to deliver a session on SignalR - which is a very useful and latest technology in .NET. The duration was about 1 hour for my session. I have uploaded the presentation slides and source codes of the sample applications in the below link

http://sdrv.ms/14KeK9M

Below are few photos taken at the event.

WellingtonPreethiRuchiraHasithaLahiruSachiraAudience 1Audience 2Audience 3Group photo

2013-08-09

Difference between Dispose and Close methods

Most of the time, we use those methods interchangeably without knowing the true context of them. Sometimes we call both of the methods. So let’s see what are the difference between those two methods and whether we should call both of the methods when we need to close a connection. I will take an SQL connection as the example,

SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Test"].ToString());
con.Open();
con.Close();
con.Open(); //2nd attempt

In the above code, the 2nd attempt would not fail. Close will simply close the connection. But it does not necessarily release the memory and do the clean up (It will release the resources temporarily). So it's possible for you to open the same connection again. Now let's use the Dispose instead and see the result

SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Test"].ToString());
con.Open();
con.Dispose();
con.Open(); //2nd attempt

Now on the 2nd attempt, it will throw me an exception saying "The ConnectionString property has not been initialized.". Why is that? That's because I have already release all the resources including the Connection String, by calling the Dispose method.

So when you are really done with a connection (If you do not wish to open it again), you should call Dispose method. It will implicitly call the Close method.

Efficient way of changing the image on hover

It’s a common thing that we change the images on mouse hover of the buttons and other selectable/clickable items. But did you notice that if the connection is slow, it takes time to render the images we are displaying on the hover state? That breaks the UI and it’s not a good user experience.

To get rid of that pain, we can use a trick. We can combine the images for the two states (hover and normal state) and set the background position on hover of the element. Something like below should work. Make sure you correctly append the two images using a photo editing software.

#imgBtn{
   background: url('/Images/SaveCombined.png');
}

#imgBtn:hover{
    background-position: 0 -50px;
}

The above CSS will set the vertical value of the background position to –50px on hover state. So, instead of swapping images on the hover state, it will simply change the background position of the one image. It will result in image position go upwards. Give the correct value for the vertical position of the background so it will display the other part of the image which should be visible for the hover state.

That’s it!

2013-08-05

Creating a self hosted app in SignalR and connect clients to it

On my previous blog posts, I’ve used a SignalR code hosted on a web server. But we can run a self hosted SignalR code and without a web application at all. On this example, I’m going to show you how to write the same chat application I’ve described here, using a console app.

First, you have to install SignalR Self hosted package using NuGet Package Manager for Visual Studio. At the moment I write this article, the package is in beta (Prerelease). So you have to select “Include Prerelease”.

Following is the code for the self hosted console application

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Hosting;
using Owin;
using System.Collections.Concurrent;

namespace SignalRSelfHosting
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "
http://localhost:8080";

            using (WebApp.Start<Startup>(url))
            {
                Console.WriteLine("Server running on {0}", url);
                Console.ReadLine();
            }
        }
    }

    class Startup
    {
        public void Configuration(IAppBuilder app)
        {

// Turn cross domain on 
var config = new HubConfiguration { EnableCrossDomain = true };

            // This will map out to http://localhost:8080/signalr by default
            app.MapHubs(config);
        }
    }

    public class ChatHub : Hub
    {
        static ConcurrentDictionary<string, string> dictionary = new ConcurrentDictionary<string, string>();

        public void Notify(string name, string id)
        {
            if (dictionary.ContainsKey(name))
            {
                Clients.Caller.differentName();
            }
            else
            {
                dictionary.TryAdd(name, id);

                foreach (KeyValuePair<String, String> entry in dictionary)
                {
                    Clients.Caller.online(entry.Key);
                }

                Clients.Others.enters(name);
            }
        }

        public void Send(string name, string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }

        public void sendToSpecific(string name, string message, string to)
        {
            // Call the broadcastMessage method to update clients.
            Clients.Caller.broadcastMessage(name, message);
            Clients.Client(dictionary[to]).broadcastMessage(name, message);
        }

        public override Task OnDisconnected()
        {
            var name = dictionary.FirstOrDefault(x => x.Value == Context.ConnectionId.ToString());
            string s;
            dictionary.TryRemove(name.Key, out s);
            return Clients.All.disconnected(name.Key);
        }
    }
}

You may note, my ChatHub class is same as I’ve used in the web application. All the methods in my hub class is same.

All you have to do is, run the console application as same as you run the web application project. This will not require a web server like IIS. The console application will use a HTTP listener and OWIN to process the HTTP requests it get. Here I’m using http://localhost:8080 as my server. So my clients should point the hub URL to that.

If we are going to change the sample JavaScript client I’ve show in below blog post,

http://ruchirac.blogspot.com/2013/02/creating-chat-application-in-aspnet.html

I’ve to add the below line at the top of the JavaScript code to tell that, use this URL as the hub connection.

$(function () {
        $.connection.hub.url = “
http://localhost:8080/signalr”;

………………

All the same, in order to point my .NET client applications I’ve described at below blog posts,

Console App - http://ruchirac.blogspot.com/2013/03/connecting-net-client-console.html

Windows Store App - http://ruchirac.blogspot.com/2013/07/connecting-windows-store-app-to-website.html

I have to pass the new URL for self hosted application when I make my hub connection. I can do it like this

var hubConnection = new HubConnection(“http://localhost:8080/signalr”);

So that’s all it take to convert the web hosted SignalR application to a self hosted console application! You don’t need a web server at all!