Click here to Skip to main content
Click here to Skip to main content

ASP.NET Chatting using WCF Services and JSon

, 1 Dec 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
ASP.NET chatting using WCF Services and JSon

Introduction

This post is an upgrade to my previous article 'Chat Application in ASP.NET Using AJAX (Pop-up Windows)', which has some disadvantages like storing chat messages in DB and little complex in adding to a website. I implemented WCF services in place of DB to make it easy for adding to a website. JSon is used for communication between server and client.

Using the Code

The basic idea is the same as the previous one, but it was modified to improve support to multiple browsers. When I ran the application on three major browsers, IE, Firefox, Chrome, it was working perfect.

If you already read the previous article, you can skip the work flow and go to the configuration section.

The application works as follows:

  • List of online users are displayed.

    Online users list is maintained by WCF service OnlineUsers.svc, logging an entry when a user logs into the application. The user names will be displayed as hyperlinks, with a unique chat ID (GUID) for each.

  • The current logged-in user will click on a user name to open a new chat window, and types a message. On clicking a username, the OpenChatBox() function is called with the chat ID as the parameter. When the user types any message and clicks on the Send button, the message is sent to the server and stored to the database with the chat ID supplied.
    var top = 100;
    var left = 100;
    function OpenChatBox(uid, chatid) 
    {    
        var hidUsr = $('input[id*="hidCurrentUser"]')[0];
        if (hidUsr.value == uid)
            return;
        var win;
        if (navigator.userAgent.toLowerCase().indexOf("chrome") != -1)
            win = window.open("Chat.aspx?uid=" + uid + "&cid=" + 
            chatid, "ChatWindow" + chatid.replace("-", "").replace
            ("-", "").replace("-", "").replace("-", ""), 
            "status=0,toolbar=0, menubar=0, width=480, height=620");
        else
            win = window.open("Chat.aspx?uid=" + uid + "&cid=" + 
            chatid, "ChatWindow" + chatid.replace("-", "").
            replace("-", "").replace("-", "").
            replace("-", ""), "status=0,toolbar=0, menubar=0, width=480, height=550");
            
        top = top + 50;
        if (top > screen.availHeight - 550)
            top = 100;
        left = left + 50;
        if (left > screen.availWidth - 450)
            left = 100;
    
        win.moveTo(left, top);
        chats[chats.length] = win;
        return false;
    }

    The message storing is implemented in ASP.NET as below. Here I am using class 'ChatMsg' (DataContract) to pass messages to chat service.

    private void SendMessage(string msg)
    {
        ChatServiceClient objChatService = new ChatServiceClient();
        ChatMsg cm = new ChatMsg();        
        cm.Msg = msg;
        cm.Sender = HttpContext.Current.User.Identity.Name;
        cm.Receiver = ViewState["uid"].ToString();
        cm.ChatId = ViewState["vwChatId"].ToString();
        cm.SubmittedDate = DateTime.Now;
        objChatService.SendMessage(cm);        
    }

    Chat_Flow.jpg

  • On the recipient's screen, a new pop-up window will appear.

    One every user's home page, a script is run every 5 seconds to ping the server for any messages.

    function PingServer() {
        PingServerForMsg()
        setTimeout(PingServer, 5000);
    }
    
    
    function PingServerForMsg() {
           // Use ajax to call the GetChatMsg.aspx to get any new messages.
    
            xmlHttp = GetXmlHttpObject(stateChangeHandler);
    }

    This JavaScript message will call the GetChat.aspx page for new messages. Here I am calling the WCF service '' to get messages and the messages will be sent to client in JSon. I am using 'JsonConvert' class from JSon.Net to serialize the list of messages. You no need to learn JSon for this application as the download includes the JSon ddl and no extra downloads are required.

    Code from GetChat.aspx.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Data;
    using WCFChatProxy;
    using Newtonsoft.Json;
    
    public partial class GetChat : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["p"] != null)
            {
                if (Request.QueryString["p"] == "read")
                {
                    ChatServiceClient objChat = new ChatServiceClient();
                    objChat.MessageStatusToRead(Request.QueryString["msgId"]);
                }
            }
            else if (Request.QueryString["cid"] != null)     //get messages for a 
                            //single chat window
            {
                Response.Clear();
                Response.ClearContent();
                Response.AddHeader("Cache-Control", "no-cache, must-revalidate");
    
                ChatServiceClient objChatService = new ChatServiceClient();
                List<chatmsg> lstMsgs = objChatService.GetMessages
                    (Request.QueryString["cid"].ToString(),
                    HttpContext.Current.User.Identity.Name,
            ChatMsgStatus.Recent).ToList();
    
                string strMsg = JsonConvert.SerializeObject(lstMsgs);
    
                Response.Write(strMsg);
                Response.End();
            }
            else // get messages for the current logged in user
            {
                Response.Clear();
                Response.ClearContent();
                Response.AddHeader("Cache-Control", "no-cache, must-revalidate");
    
                ChatServiceClient objChatService = new ChatServiceClient();
                List<chatmsg> lstMsgs = objChatService.GetMessagesByUserId
                (HttpContext.Current.User.Identity.Name).ToList();
    
                string strMsg = JsonConvert.SerializeObject(lstMsgs);
    
                Response.Write(strMsg);
                Response.End();
            }
        }
    }

    On the browser side, on getting a new message, the browser will open a pop-up if the chat ID is new, or will show the message if a pop-up is already open for the chat ID associated with the new message. And here, an additional change to the old article is that on receiving message, browser sends an acknowledgement to server and server marks the message as read.

    function stateChangeHandler() {
        //readyState of 4 or 'complete' represents that data has been returned 
        if (xmlHttp.readyState == 4 || xmlHttp.readyState == 'complete') {
            //Gather the results from the callback 
            var str = xmlHttp.responseText;
            if (str != "") {  
                var chatmsgs = eval(str);
                for (ind = 0; ind < chatmsgs.length; ind++) {
                    var senderId = chatmsgs[ind].Sender;
                    var chatId = chatmsgs[ind].ChatId;
                    var message = chatmsgs[ind].Msg;
                    var msgId = chatmsgs[ind].MsgId;
    
                    message = restoreHtmlTags(message);
                    document.getElementById('msgPanel').innerHTML += "
    " + senderId + ": " + message;
                    MessageReceived(msgId, msgCounter);
    
                    document.getElementById('msgPanel').scrollTop = 
                document.getElementById('msgPanel').scrollHeight;
                }
            }
        }
    } 
  • Users can communicate through the current window.

    The recipient can type in a message to reply back using the same window. The pop-up window has the screen Chat.aspx, which has the Chat.js reference of the JavaScript code to ping the server again every second. But this time, it uses the chat ID assigned to that window. And thus, every chat has a unique chat ID, and chat messages are maintained at the backend by the chat ID, and the pop-up windows communicates through the chat ID. An UpdatePanel is used here to avoid flickering of the chat window when the user clicks Send Message. And when a message is received by the recipient, the message is deleted at the server.

    User can type in HTML tags also to send messages with different fonts and size. Here, developers can customize the application to give end users an option to set their own styles by selecting fonts and size drop downs. Here in the below screenshot, I am typing the font color and size.

    Chat_fonts.jpg - Click to enlarge image

  • A single user can communicate with multiple users at a time.

    A user can chat with any number of users as pop-up windows are used for each chat with a unique chat ID for the chat.

    multi_browser.jpg - Click to enlarge image

Steps to Configure in Your Website

  • Create a new website or open your ASP.NET project in which you want to add the chat pages.
  • Download the attached zip file, unzip and copy folder 'ChatService' to local drive. Configure a virtual directory/Application with any name (say 'WCFChatService') in IIS and make it working under .NET 4.0. Check whether http://localhost/<your_service_app_name>/WCFChat.svc and http://localhost/<your_service_app_name>/OnlineUsers.svc are opening the browser. You can test with WCFTestClient (http://msdn.microsoft.com/en-us/library/bb552364.aspx) also.
  • Add service references to both the services in your website.
  • Add reference to Newtonsoft.Json.dll in your website. Get the DLL from 'ChatClient\Bin' if you don't want to download from JSon.Net site.
  • In your website's log-in page, on successful log-in, add the following code to add the user to online users list:
    OnlineUsersProxy.OnlineUsersServiceClient objOnlineUsers = 
            new OnlineUsersProxy.OnlineUsersServiceClient();
    Member mem = new Member();
    mem.UserId = txtUserID.Text;
    mem.DisplayName = GetDisplayNameById(mem.UserId); //write your own method
    objOnlineUsers.AddOnlineUser(mem);            
    
    //redirect home page
  • Copy Chat.aspx and GetChat.aspx to your website folder and Chat.js and ChatWindow.js files to Scripts subfolder. Copy the below tags for repeater control to your home page where you want to show online users.
  • Online users:<br />
        <asp:Repeater ID="rptrOnlineUsers" runat="server">
             <ItemTemplate>                                        
              <span style="cursor:hand;text-decoration:underline;" 
        onclick="OpenChatBox('<%#((OnlineUsersProxy.Member)
        Container.DataItem).UserId%>','<%#((OnlineUsersProxy.Member)
        Container.DataItem).ChatId%>')"><%#((OnlineUsersProxy.Member)
        Container.DataItem).DisplayName%></span><br />
             </ItemTemplate>
        </asp:Repeater><span class="Apple-tab-span" style="white-space: pre; ">    
        </span>   
    <input type="hidden" id="hidCurrentUser" runat="server" /> 
  • Add below code in Page_Load for binding online users to repeater. Here I am saving the current logged in user id in hidden field which is used later in chat.
    hidCurrentUser.Value = HttpContext.Current.User.Identity.Name;
    
    OnlineUsersProxy.OnlineUsersServiceClient wsOnlineUsers = 
            new OnlineUsersProxy.OnlineUsersServiceClient();
    rptrOnlineUsers.DataSource = wsOnlineUsers.GetOnlineUsers
                (HttpContext.Current.User.Identity.Name);
    rptrOnlineUsers.DataBind(); 
  • Run your project to test ..... Smile | :)

Points of Interest

I hope using WCF and JSon.Net in place of DB will be a better solution, and while improving this, I got a chance to fix issues with other browsers, Firefox and Chrome.

Enhancements

  • WCF service stores the messages in memory and I implemented few methods to free memory by deleting old messages. And user can call these methods on log-out to remove logged out user messages.
  • Developers can try to implement saving the chat history.
  • The list of online users can be implemented in a user control to make it reusable and to show image of the user as it uses repeater control.
  • I used simple design for chat window and it can be changed to include the time of message and images.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Narsimlu Keshagouni
Technical Lead Weston Solutions
India India
Hi, I am Narsimlu Keshagouni working as Technical Lead in Hyderabad, India. I work on the technologies:
 
-ASP.NET
-Silverlight
-WCF
-SQL Server
-SSRS

Comments and Discussions

 
QuestionWCF chatting [modified] PinmemberMember 1068140630-May-14 10:02 
QuestionOnlineUsers method is not refreshing Pinmembermadhavi_0814-May-14 22:31 
Questioni don't know how to configure the virtual directory PinmemberMember 1008169022-Mar-14 4:53 
QuestionLoad Testing Pinmembersachin.vishwa901-Feb-14 3:51 
Questionsir please help Pinmembershreyasm198318-Dec-13 0:43 
Questionall steps performed getting error after Pinmembercyber_addicted12-Nov-13 21:01 
Generalchatting Pinmemberaiswarjya20-Aug-13 0:59 
Questionbase address settings PinmemberMember 1010841616-Jun-13 19:14 
GeneralEasiest way to create and consume WCF Services in asp.net PinmemberLalit24rocks14-May-13 22:47 
QuestionRunning the project localhost howto??? Pinmembersimpa26-Mar-13 1:16 
AnswerRe: Running the project localhost howto??? PinmemberMember 106386176-Mar-14 1:35 
QuestionMessages not going PinmemberMember 814812914-Mar-13 2:12 
QuestionDon't Know How to configure IIS Plz help me. PinmemberMember 876390530-Dec-12 19:02 
QuestionCan you plz help me on this ... Pinmemberblrsimon18-Oct-12 0:47 
GeneralRe: Can you plz help me on this ... PinmemberNarsimlu Keshagouni8-Nov-12 20:38 
QuestionPlease, help Pinmemberlý đình thành2-Oct-12 22:10 
BugSending and receiving of messages PinmemberPooja Somasundar1-Aug-12 19:43 
GeneralRe: Sending and receiving of messages Pinmemberravi KANT garg16-Sep-12 7:44 
GeneralRe: Sending and receiving of messages PinmemberNarsimlu Keshagouni21-Sep-12 1:06 
QuestionRegarding a minor issue PinmemberPooja Somasundar25-Jul-12 22:00 
AnswerRe: Regarding a minor issue PinmemberNarsimlu Keshagouni21-Sep-12 1:08 
Generalfilter users on the default page [modified] Pinmembermartinr8429-Jun-12 9:33 
GeneralRe: filter users on the default page PinmemberNarsimlu Keshagouni3-Jul-12 0:29 
Questionplease reply for this error Pinmemberjagadeesh3111-May-12 17:12 
AnswerRe: please reply for this error PinmemberNarsimlu Keshagouni14-May-12 1:43 
QuestionPlease help Me Pinmemberjpr chaitanya27-Apr-12 2:18 
AnswerRe: Please help Me PinmemberNarsimlu Keshagouni27-Apr-12 19:54 
GeneralRe: Please help Me [modified] Pinmemberjpr chaitanya29-Apr-12 19:08 
QuestionRegards WCF service in local host Pinmembermanojprabakaran12-Apr-12 14:12 
Questionplz help me it gives an error. PinmemberMember 788745527-Mar-12 23:16 
AnswerRe: plz help me it gives an error. PinmemberNarsimlu Keshagouni3-Apr-12 4:24 
QuestionASP.NET Chatting using WCF Services and JSon [modified] PinmemberMember 875383424-Mar-12 22:27 
AnswerRe: ASP.NET Chatting using WCF Services and JSon PinmemberNarsimlu Keshagouni27-Mar-12 15:45 
If step 2 is not working, the service is not workin and there may be something wrong with your configuration. First check if the service is running by copying the url of the service to browser and see if the service is running, if not it will show the error message. Correcting the step 2 will fix step 3 also.
 
Or if you are unable to fix, please send me the screenshot by copying url of the service to address of the browser.
QuestionNotifying the user. Pinmemberbutters198222-Mar-12 6:34 
AnswerRe: Notifying the user. PinmemberNarsimlu Keshagouni27-Mar-12 15:49 
GeneralRe: Notifying the user. Pinmemberbutters19829-Apr-12 10:44 
GeneralRe: Notifying the user. Pinmemberjpr chaitanya30-Apr-12 1:05 
GeneralRe: Notifying the user. Pinmemberjpr chaitanya27-Apr-12 2:31 
GeneralHelp on the Article "ASP.NET Chatting using WCF Services and JSon" PinmemberDeepak1414141415-Mar-12 21:58 
GeneralRe: Help on the Article "ASP.NET Chatting using WCF Services and JSon" PinmemberNarsimlu Keshagouni15-Mar-12 23:13 
QuestionImports WCFChatProxy [modified] PinmemberJohn Windsor13-Dec-11 13:45 
AnswerRe: Imports WCFChatProxy PinmemberNarsimlu Keshagouni15-Dec-11 18:44 
Suggestionfeature set PinmemberGary Noter6-Dec-11 13:21 
GeneralRe: feature set PinmemberNarsimlu Keshagouni7-Dec-11 1:50 
GeneralRe: feature set Pingroupkishorebt27-May-14 20:21 
GeneralRe: feature set Pingroupkishorebt27-May-14 22:41 
GeneralMy vote of 5 PinmemberMonjurul Habib2-Dec-11 5:47 
GeneralMy vote of 5 Pinmemberburak2992-Dec-11 4:53 
GeneralMy vote of 4 PinmemberSercanOzdemir2-Dec-11 1:59 
BugIssue in Framework 3.5 PinmemberSuresh Chathuranga28-Nov-11 23:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141216.1 | Last Updated 2 Dec 2011
Article Copyright 2011 by Narsimlu Keshagouni
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid