SignalR with Windows Azure Cloud Services

My last sample with SignalR has shown a very simple chat server and client – I know that is a very lame example, but it shows the important things about SignalR. The chat server was a console application which makes it very hard to handle in some scenarios. What if the chat clients are located in different cities or countries and not in the same network? In that case, the console application is useless and the Azure Cloud Service from Microsoft comes in handy.

This example uses the Window Azure Web Role. After creation of a trail account (The first three months are free), you can set up a Web Role with the Windows Azure Portal. Makes sure you set the correct region, because of server performance.

Azue01

After the creation you’ll have to download and install the Azure SKD for .NET for your Visual Studio version. Only Visual Studio 2010 and 2012 works with the SKD, but I’m quite sure no one is using older versions.

http://www.windowsazure.com/en-us/develop/net/

Now you can create a new project using the Windows Azure template and add a Web Role Service to the project.

Azure02

Azure03

The web role template comes with a huge amount of files, which are useless for this example. So, delete all files and folders, except these:

Azure04b

All necessary references for the project can be added with NuGet. The Microsoft ASP.NET SignalR SystemWeb package contains everything for applications hosted with IIS.

Azure04

Like the old server, the azure server needs to have a Hub, which is called ChatHub similar to the last example.


[HubName("ChatHub")]
public class ChatHub : Hub
{
    public Task SendMessage(string message)
    {
        String formatedMessage = String.Format("{0}: {1}", Global.Users[Context.ConnectionId], message);

        return Clients.All.addMessage(formatedMessage);
    }

    public Boolean Join(string username)
    {
        Global.Users.Add(Context.ConnectionId, username);

        Clients.Others.addMessage(username + " joined the chat.");

        Console.WriteLine(Context.ConnectionId + " (" + username + ") connected.");

        return true;
    }

    public List<String> GetUsers()
    {
        return Global.Users.Values.ToList<String>();
    }
}

The Global.ashx file that holds methods, which being called if the web application starts for the first time (Side node: The IIS shuts down the application if no user is active and starts if a request came in), contains the initialization and the configuration for the ChatHub. Furthermore the file contains a static Dictionary that saves the user.


public class Global : HttpApplication
{
    public static Dictionary<String, String> Users = new Dictionary<string, string>();
        
    void Application_Start(object sender, EventArgs e)
    {
        HubConfiguration hubConfiguration = new HubConfiguration();
        hubConfiguration.EnableJavaScriptProxies = false;

        RouteTable.Routes.MapHubs("/chatserver", hubConfiguration);
    }

    void Application_End(object sender, EventArgs e)
    {
        //  Code that runs on application shutdown

    }

    void Application_Error(object sender, EventArgs e)
    {
        // Code that runs when an unhandled error occurs

    }
}

The default.aspx is used to display the Url of the application. Nothing more

protected void Page_Load(object sender, EventArgs e)
{
    string currentUrl = String.Empty;

    if (Request.ServerVariables["HTTPS"].ToString() == "")
    {
        currentUrl = Request.ServerVariables["SERVER_PROTOCOL"].ToString().ToLower().Substring(0, 4).ToString() + "://" + Request.ServerVariables["SERVER_NAME"].ToString() + ":" + Request.ServerVariables["SERVER_PORT"].ToString();
    }
    else
    {
        currentUrl = Request.ServerVariables["SERVER_PROTOCOL"].ToString().ToLower().Substring(0, 5).ToString() + "://" + Request.ServerVariables["SERVER_NAME"].ToString() + ":" + Request.ServerVariables["SERVER_PORT"].ToString();
    }

    Response.Write("Server is running on " + currentUrl);
}

After a successful build, the application can be published to Azure. The publishing is very easy. It all starts with a publishing file, which contains all needed settings. The file can be downloaded from the Azure Portal. Click on the Website and choose the link “Download publish profile”.

Azure05

Azure06

With the Command “Publish” in the project setting the process will be started. I am not sure why the command “Publish to Windows Azure” is much more complicated as Publish. Import the settings file and start to start the publishing.

Azure07

So, call the Url with a browser and make sure that everything works fine. To make the Client work, set up the Url in the source code in the Form1.


private void Form1_Load(object sender, EventArgs e)
{
    SetStatus("Connecting");
    connection = new HubConnection("http://YOUR_URL/chatserver", false);

    myHub = connection.CreateHubProxy("ChatHub");

If everything is correct, the client communicates with the server.
This is only a first step in Windows Azure and I am not sure if this is the right or the best way. But it works!

The whole Visual Studio Solution can be found on GitHub.

Advertisements
This entry was posted in ASP.NET, Azure, C#, Development and tagged , . Bookmark the permalink.

One Response to SignalR with Windows Azure Cloud Services

  1. That’s great, but how will your solution behave when there’s an azure loadbalancer present with … say 3x instances of the said web role?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s