At Telerik, we receive MANY requests for features and support on our Telerik Feedback Portal. Sometimes we'll get outlandish suggestions along the lines of, "Hey, it would be great if you had a control that would make unicorns dance on screen." We can't accommodate every request, but we watch the feedback portal closely and respond to as many popular requests as possible. One request that we have heard a number of times, most recently surfacing this January, is about a chat component with our UI for ASP.NET toolset.
In this article, I'm going to walk through setting up a page with chat capabilities using several of the Telerik ASP.NET controls: Splitter, ListView, and Notifications. I'm not only going to show you how to effect the communication between clients, I'm also going to show you how to allow the chat operation to use rich HTML with the RadEditor control as well.
In our ASP.NET controls, we now have extensive capabilities built in to allow your web pages to size appropriately for any device that requests your content. For this chat room, I want something similar so that visitors using a tablet, phone, or a desktop device can easily interact with the chat room.
To start, I implemented a simple three pane layout using the RadSplitter and RadPane controls. That layout markup in my ASPX page looks like the following:
The RadPanes are allocated so that the users can stretch and size the various parts of the screen appropriately. By indicating that the RadSplitter container controls have a width and height of 100%, the layout will stretch to fill the containing document elements appropriately.
On the right side of the screen, I've allocated a panel with a
rightPanel that will contain my current list of chatters in the room. To present this list, I'll use a RadListView control with ASP.NET ModelBinding and strong typing to load the current chatter list while this ASP.NET page is being rendered on the server. This markup is simple, and looks like the following:
This layout looks fairly simple, but there are some neat ASP.NET 4.5 features going on here. The
SelectMethod attribute defines a server-side method in the code-behind of my page that will fetch a collection of
Telerik.AjaxChat.Models.User objects to present in this list. The template uses ASP.NET data binding to create a standard HTML unordered list with the name of the chatter as part of the ID and text of the list-item. More on that
GetChatters method in a bit, as we next look at how the text editor is formatted on screen.
When I think of text entry on the web, I want to coolest and most powerful capabilities at my fingertips. Standard textboxes are passé because I want to be able to mark things as bold or underlined or even italicized when I chat. Further, I want to be able to use emoticons on screen to convey exactly what I am thinking. Fortunately for us, Telerik RadEditor can do all of that and make you look really smart at the same time.
The markup for the RadEditor is initially simple:
Once again, there's no rocket science going on here. A simple event handler attached to the
onKeyUp event of the editor that detects if the enter key was released and calls a
SendMessage method with the HTML currently in the editor. We'll look at the
SendMessage method when we start to connect this markup to the chat service.
The default RadEditor has a TON of great editor features on it, but there are some that aren't really useful for chatting. Plus, I really want a cool emoticon feature in my editor. Fortunately, the RadEditor supports custom toolbars with custom buttons… BONUS!
I can redefine the toolbar on my RadEditor by adding the following Tools child-element to the markup:
With this markup I now have the default Bold, Italic, Underline, and StrikeThrough toolbar buttons. I've added a custom Emoticons button with images of emoticons that are presented in a drop-down by using the
EditorDropDownItem elements. Finally, I've added the default
AjaxSpellCheck button, and defined the hotkey of F7 to trigger a spell check of words in my editor.
OnClientCommandExecuting attribute of my editor. That code to handle the emoticon toolbar button looks like this:
That was almost too easy… There is a complete example of building custom toolbar buttons and features available on our Telerik Sample Pages.
The server-side component that holds this together is a SignalR hub. To add a SignalR hub to your ASP.NET project, enter the standard "Add Item to Project" dialog and search for SignalR hub. When you add this item type to your project, Visual Studio is smart enough to add the appropriate Nuget packages to your project.
The one step you will need to do manually for your project, is map the SignalR hubs in the ASP.NET router. This is easy to do, but you need to remember that SignalR is now exclusively supported using the OWIN framework for ASP.NET. OWIN is the new Open Web Interfaces for .NET architecture that ASP.NET is embracing to allow ASP.NET frameworks to more easily interoperate. As a good citizen in this new architecture, we need to configure SignalR in the new
Startup.cs class that you should find on the root of your ASP.NET application:
Nothing to it, the only tricky thing about it is that we need to remember that these types of startup activities are moving out of the Global.asax file and into the Startup process.
The ChatHub contains one real method for interaction with the clients:
Broadcast. That method will notify all attached clients by calling the
That couldn't be any more straightforward, we're simply going to pass the text along to all of the clients, indicating the
CurrentUserName who submitted the message and the body of the HTML message that was submitted to the service. The
CurrentUserName is a property that fetches the name of the acting user from a collection of currently connected users. How do I manage that list of currently connected users? That's an easy task with the built in
OnDisconnected methods of the base
Microsoft.AspNet.SignalR.Hub class that the ChatHub descends from.
One thing I ran into was that multiple threads accessing instances of this ChatHub object would interact with the dictionary of current chatters. To allow for that interaction, I created a static
ConcurrentDictionary to protect the thread access to reading and writing the current list of chatters.
I've added appropriate calls to the
OnDisconnected methods to search the
ApplicationUserManager object to find the user who is currently authenticated on the service. Detailed definitions of those objects are included in the attached source code with this article.
The final thing to note about these connected and disconnected events on the server is that when the event is finished, I notify all clients of the connection or disconnection. This will allow me to use a RadNotification to pop a 'toast' message on screen so that you know when your buddies are coming online and to manage the list of chatters on screen.
Remember earlier, I indicated a
SelectMethod to get the list of current chatters on my web form? Now that you've seen where I am storing that dictionary, I can write that select method to return users to the
I can then create a reference variable for the ChatHub and write a self-executing function to run at startup that will connect to the service and start listening for messages.
This code will start the connection, and it will handshake with the SignalR library using whatever protocols are available in the browser. Great, now we just need to connect that
SendMessage function to send messages to the server.
What makes this method really interesting is that the
chatHub object is generated by the server from the C# code in the
How do the other clients receive it and have it painted on their screens? When the
Broadcast method is called on the server, it relays the HTML to all clients by calling the
This simply receives the message and appends it to the messages panel using the jQuery append method with some formatting to indicate who sent the message.
Next, let's handle the notification of new chatters. I've added a RadNotification to the markup with syntax like the following:
This will allow me to push a 'toast' notification on the bottom right of the screen as chatters connect to the service. The method to listen for the connection event called from the server is called
notifyConnection and has the following code:
This method receives the name of the user connecting, looks for an element that has that user's name and adds it, if it does not exist, using another jQuery append method. Finally, the RadNotification object is configured with appropriate text to show that someone joined the room and that message is displayed. The control will automatically hide it after the five seconds defined in the RadNotification
What do we do when a user disconnects? Simple, we remove their name from the list when the
notifyDisconnection method is called.
The screen looks simple, but has a lot of power buried in it thanks to our editor and SignalR bindings:
Take it for a spin. Let me know what you think of this configuration, and see how you can extend it. This code has some limitations, so let me know how you would extend it or improve it. You can even send me a pull-request on BitBucket and we will update the sample appropriately.
Jeffrey T. Fritz is a Microsoft MVP in ASP.Net and an ASPInsider with more than a decade of experience writing and delivering large scale multi-tenant web applications. After building applications with ASP, ASP.NET and now ASP.NET MVC, he is crazy about building web sites for all sizes on any device. You can read more from Jeffrey on his personal blog or on Twitter at @csharpfritz. Google Profile CodeProject
Subscribe to be the first to get our expert-written articles and tutorials for developers!
All fields are required