Showing posts with label geotopia. Show all posts
Showing posts with label geotopia. Show all posts

Monday, October 21, 2013

Geotopia: searching and adding users (Windows Azure Cache Service)

Now that we are able to sign in and add geotopic, the next step would be to actually find users and follow them. The first version of Geotopia will allow everybody to follow everybody, a ring of authorization will be added in the future (users need to allow you to follow them after all).

For fast access and fast search, I decided to use the Windows Azure Cache Service preview to store a table of available users. An entry in the cache is created for everyone that signed up.

First of all, I created a a new cache on the Windows Azure portal.


Azure now has a fully dedicated cache for me up and running. Every created cache has a default cache that is used when no additional information is provided.

Next step is to get the necessary libraries and add them to my webrole. Use the Nuget package manager to get them and search for Windows Azure Caching. This will add the right assemblies and modifies the web.config. It adds a configsection to the configuration file (dataCacheClients).

Now with the cache in place and up and running, I can start adding entries to the cache when somebody signs up and make him/her available in the search screen.

Later on, we can also cache Page Output (performance!) and Session State (scalability).

I also created a controller/view combination that allows users to signup with simply their username and an emailaddress. The temporarily password will be sent to this email account.

Download the Windows Azure AD  Graph Helper at http://code.msdn.microsoft.com/Windows-Azure-AD-Graph-API-a8c72e18 and add it to your solution. Reference it from the project that needs to query the graph and create users.

Summary
The UserController performs the following tasks:
1. Add the registered user to Windows Azure Active Directory by using the Graph Helper
2. Adds the user to the neo4j graph db to enable it to post geotopics
3. Add the user to the Windows Azure Cache to make the user findable.

This snippet does it all.

            string clientId = CloudConfigurationManager.GetSetting("ClientId").ToString();
            string password = CloudConfigurationManager.GetSetting("ClientPassword").ToString();
            // get a token using the helper
            AADJWTToken token = DirectoryDataServiceAuthorizationHelper.GetAuthorizationToken("", clientId, password);
            // initialize a graphService instance using the token acquired from previous step
            DirectoryDataService graphService = new DirectoryDataService("", token);
            //add to Neo4j graph
            GeotopiaUser user1 = new GeotopiaUser(user.UserName, user.UserName, user.UserName + "@geotopia.onmicrosoft.com");

            var geoUser1 = client.Create(user1,
                new IRelationshipAllowingParticipantNode[0],
                new[]
                            {
                                new IndexEntry("GeotopiaUser")
                                {
                                    { "Id", user1.id.ToString() }
                                }
                            });
            //add to cache
            object result = cache.Get(user.UserName);
            if (result == null)
            {
                // "Item" not in cache. Obtain it from specified data source
                // and add it.
                cache.Add(user.UserName, user);
            }
            else
            {
                Trace.WriteLine(String.Format("User already exists : {0}", user.UserName));
                // "Item" is in cache, cast result to correct type.
            }

The modal dialog on the Geotopia canvas searches the cache every time a keydown is notices and displays the users that meet the query input of the dialog.

Monday, October 14, 2013

Geotopia, SignalR and Notification Hub

The next extension of Geotopia is to notify users of updates. Everyone who is following 'me', should get a notification of a topic I posted. Install SignalR by using the package manager console or the Manage nuget packages screen when you right-click the asp.net project. E.g. in the package manage console, run:

Install-Package Microsoft.AspNet.SignalR -Version 1.1.3.

You can also use newer versions of SignalR.

In the webapi controller that handles the creation of Geotopics, I also update all the clients with this newly created Geotopic.

The SignalR hub is lazy loaded by the Geotopic webapi controller.

protected readonly Lazy AdminHub = 
            new Lazy(() => GlobalHost.ConnectionManager.GetHubContext());


The webapi method Post is slightly modified and calls the posted method on the clients.

[System.Web.Http.Authorize]
        public void Post(Geotopic value)
        {    

            //user must be logged in.
            var userNode = client.QueryIndex("GeotopiaUser", IndexFor.Node, String.Format("Id:{0}", User.Identity.Name));

            //now create a topic
            Geotopic newTopic = new Geotopic(value.latitude, value.longitude, value.message);

            var secondtopic = client.Create(newTopic,
                new IRelationshipAllowingParticipantNode[0],
                new[]
                            {
                                new IndexEntry("Geotopic")
                                {
                                     { "Id", newTopic.id.ToString() }
                                }
                            });
            NodeReference reference = userNode.First().Reference;

            client.CreateRelationship(secondtopic, new PostedBy(reference));
            //now SignalR it to all my followers....
            AdminHub.Value.Clients.All.posted(value);
   }

A piece of Javascript makes all of the above happen. It connects to the geotopichub and responds to the "posted" call from the webapi controller.



To show a nice popup on the Geotopiascreen I use Toastr. Get this by: install-package Toastr.

When I post a topic, the Toastr package displays a nice toast:



The SignalR addition enables webclients to be updated on the fly. For future release of mobile clients of Geotopia, I also use the Notification Hub of Windows Azure to enable notifications on mobile devices. To enable this, I create a service bus namespace and a notification hub.


Now I have a notificationhub available. A mechanism to easily update my mobile clients. On the backend side (my webrole), install the service bus package.

Install-Package WindowsAzure.ServiceBus

add use it in your designated class. In my case, I use it in my TopicsController.cs webapi module.

using Microsoft.ServiceBus.Notifications;

I add the following lines to the Post method of my TopicsController:
  NotificationHubClient myNotificationHub = NotificationHubClient.
        CreateClientFromConnectionString("Endpoint=sb://.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=;YOUR_KEY", 
            "YOUR_HUB");
 string toast = "" +
                "" +
                    "" +
                        "A toast from geotopia!" +
                    "
" +                "
";
 Task result = myNotificationHub.SendMpnsNativeNotificationAsync(toast);

In the result we can see the outcome of the notification call.

For now, everybody receives notifications of topics being posted. The next blog post will demonstrate how to make sure only my followers get my topics by using SignalR groups and adding tags for the Notification Hub.