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

Build a Web based Chat using ASP.NET Ajax

, 24 Feb 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
Build a GMail like web based chat using ASP.NET Ajax that can handle several requests and simultaneous users
SampleChat
Screenshot of a conversation using the chat

Introduction

I will show you how to build a Web-based chat using ASP.NET 2.0/3.5, ScriptServices and a SQL Server database, that can handle several requests and simultaneous users.

The source provided is pretty much ready to be copied and pasted into any 3.5 web application.

Requirements

  • The chat application must be HTTP-based. No other protocol allowed.
  • The application must allow multiple chat rooms.
  • The user can leave the room without notifying the application.
  • The list of chatters in the room must reflect the latest changes with a delay not greater than (for example) 5 seconds.
  • The messages list must be retrieved with a delay not greater than (for example) 2 seconds.

Application State

As in HTTP the connection is closed after a single request/response pair, you have to simulate the status of being connected to the chat room. I accomplish that by having an application state object of the chat users. Also, as you don't have a notification when the user is disconnected, you will have to check regularly for the latest activity from the user in order to manually remove it from the chat users list.

public void ValidateUsers(TimeSpan maxInterval)
{
    List<int> toDelete = new List<int>();
    foreach (System.Collections.Generic.KeyValuePair<int> keyValue in this.Users)
    {
        //Identify which users don't have recent activity
        if (DateTime.Now.Subtract(keyValue.Value.LastActivity) > maxInterval)
        {
            toDelete.Add(keyValue.Key);
        }
    }
    //Remove them from the current users list
    //...
}        

Ajax Enabled Webservice

The Ajax service exposes four methods:

  • EnterRoom: It assigns the user to the chat room by adding the user to the room users list.
  • CheckMessages: It's responsible to get the latest message from the database and check the users list.
  • SendMessage: It saves the message and checks the users list, returning the latest messages.
  • CheckUsers: It validates all the users list from the chat room by getting the latest activity from the users and, if the list changed, returns the new users list.

Client Scripting

The client script is responsible to refresh the list of messages on the screen by using setTimeout to Ajax calls.

Here you can see the JavaScript that makes the request to the webservice and its callbacks.

Codeproject.Chat.EnterRoom = function()
{
    //Calls the web service to enter the chat
    SampleChat.Chat.Services.ChatService.EnterRoom(Codeproject.Chat.RoomId,
        Codeproject.Chat.EnterRoomCallback);
}
//EnterRoom Callback
Codeproject.Chat.EnterRoomCallback = function(lastMessageId)
{
    //Store the last message id in a JavaScript global variable
    Codeproject.Chat.LastMessageId = lastMessageId;
    //Remove the loading message
    Codeproject.Chat.MessagePanel.className = "";
    //Get the users list
    Codeproject.Chat.CheckUsers();
    //Get the messages list
    Codeproject.Chat.CheckMessages();
}
//Updates the users list
Codeproject.Chat.CheckUsers = function ()
{
    //Check and validate users in the webservice
    SampleChat.Chat.Services.ChatService.CheckUsers(Codeproject.Chat.CheckUsersCallback);
    //Timer to check users
    setTimeout(Codeproject.Chat.CheckUsers, Codeproject.Chat.CheckUsersRefresh);
}
Codeproject.Chat.CheckUsersCallback = function(response)
{
    if (response.Users.length > 0)
    {
        Codeproject.Chat.ArrangeUsers(response.Users);
    }
}
Codeproject.Chat.CheckMessages = function ()
{
    //Calls the web service to check for new messages
    SampleChat.Chat.Services.ChatService.CheckMessages(Codeproject.Chat.LastMessageId,
        Codeproject.Chat.CheckMessagesCallback);
    //Set the timer to check the messages next time.
    setTimeout(Codeproject.Chat.CheckMessages, Codeproject.Chat.CheckMessagesRefresh);
}
Codeproject.Chat.CheckMessagesCallback = function(response)
{
    if (response.Messages.length > 0)
    {
        //Store the last message id
        Codeproject.Chat.LastMessageId = response.LastMessageId
        //Show the latest message in the message list
        Codeproject.Chat.ArrangeMessages(response.Messages);
    }
    if (response.Users.length > 0)
    {
        //Show the latest message in the message list
        Codeproject.Chat.ArrangeUsers(response.Users);
    }
}
Codeproject.Chat.SendMessage = function ()
{
	var message = Codeproject.Chat.MessageTextbox.value;
	if (message.trim() != "")
	{
		SampleChat.Chat.Services.ChatService.SendMessage(message,
			Codeproject.Chat.LastMessageId,
			Codeproject.Chat.CheckMessagesCallback);
		Codeproject.Chat.MessageTextbox.focus();
		Codeproject.Chat.MessageTextbox.value = "";
	}
}

All the client script needed to run the chat is provided in the source under the namespace: Codeproject.Chat.

Database

Here is the design of the database table used by the chat.

As the amount of records may grow a lot in a few hours/days, it's very important to query this table through its clustered index, getting only the new messages since the previous message you retrieved (storing in the user state the Id of the last message retrieved).

CREATE TABLE [dbo].[ChatMessages](
    [MessageId] [int] IDENTITY(1,1) NOT NULL,
    [RoomId] [int] NOT NULL,
    [MessageBody] [varchar](250) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [MessageDate] [datetime] NOT NULL,
    [UserId] [int] NOT NULL,
    [IsSystem] [bit] NOT NULL,
 CONSTRAINT [PK_ChatMessages] PRIMARY KEY CLUSTERED
(
    [MessageId] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

Hope you enjoy it!

History

  • March 2nd, 2009 - Article submitted
  • March 9th, 2009 - Article body extended
  • February 24th, 2010 - JS improved

License

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

Share

About the Author

Jorge Bay Gondra
Software Developer
Spain Spain
Jorge has been working in Software development for more than 10 years. Born in Argentina, he lives in Spain since 2004.
 
He worked as a consultant for mayor companies including Log, HP and Avanade and holds some technical certifications including MCSD and MCAD.
 
He is the founder of the asp.net mvc forum open source project Nearforums, the Node.js Cassandra driver and the owner of the news release site prsync.com.
 
Follow him on Twitter: twitter.com/jorgebg
 
Contact: jorgebaygondra at gmail
Follow on   Twitter

Comments and Discussions

 
QuestionSMS chatting Pinmemberineedfriday12-Sep-14 7:56 
QuestionI am using this chat project made by you. PinmemberADI@34518-Jun-14 23:32 
Questionmessage panel name not change: PinmemberMember 1041795922-Nov-13 22:29 
QuestionThank you - think this will be great but I'm getting an error in the web.config so can't run it yet [modified] PinmemberMember 34028866-Nov-13 20:31 
QuestionSCRIPT5022: Sys.Net.WebServiceFailedException in iFrame Pinmembersiva@attur1219-Aug-13 5:01 
GeneralMy vote of 5 Pinmembercsharpbd13-Nov-12 19:57 
QuestionGood work PinmemberMember 878265930-Oct-12 23:21 
AnswerRe: Good work PinmemberJorge Bay Gondra30-Oct-12 23:54 
QuestionGood PinmemberAjay Kumar Tiwari From Mumbai4-Jun-12 3:49 
Questioncall masterpage at runtime Pinmemberuuttam-kumar28-Mar-12 21:52 
QuestionMicrosoft JScript runtime error: 'Codeproject' is undefined Pinmembermmckaarshe31-Jan-12 7:47 
AnswerRe: Microsoft JScript runtime error: 'Codeproject' is undefined PinmemberJorge Bay Gondra1-Feb-12 22:43 
QuestionCould not load type 'SampleChat.Chat.Controls.Chat Pinmembersolutioner9911-Dec-11 23:24 
AnswerRe: Could not load type 'SampleChat.Chat.Controls.Chat PinmemberJorge Bay Gondra11-Dec-11 23:41 
GeneralRe: Could not load type 'SampleChat.Chat.Controls.Chat Pinmembersolutioner9912-Dec-11 1:03 
GeneralRe: Could not load type 'SampleChat.Chat.Controls.Chat PinmemberJorge Bay Gondra12-Dec-11 1:45 
GeneralRe: Could not load type 'SampleChat.Chat.Controls.Chat Pinmembersolutioner9912-Dec-11 1:53 
Question2chat room Pinmembervidyasagarreddy1435-Dec-11 21:38 
QuestionMejora PinmemberRichardEm14-Oct-11 10:09 
Questionhow to add room id dynamically Pinmembermahabubur rahman3-Oct-11 0:42 
AnswerRe: how to add room id dynamically Pinmembertamannashah199315-Nov-11 23:51 
GeneralRe: how to add room id dynamically Pinmembermahabubur rahman16-Nov-11 1:42 
QuestionDatabase Problem PinmemberRichardEm27-Sep-11 13:00 
AnswerRe: Database Problem PinmemberJorge Bay Gondra27-Sep-11 22:49 
QuestionMy vote of 5 PinmemberFilip D'haene8-Sep-11 7:23 
AnswerRe: My vote of 5 PinmemberJorge Bay Gondra27-Sep-11 22:49 
QuestionCan Anybody pls code this project in simple way Pinmemberhijagdeep1-Sep-11 9:20 
AnswerRe: Can Anybody pls code this project in simple way PinmemberJorge Bay Gondra1-Sep-11 23:24 
QuestionCannot run this. PinmemberMember 182069324-Aug-11 0:51 
GeneralMy vote of 5 Pinmemberaloknetuser5-Aug-11 4:07 
GeneralMultiusuarios Pinmemberjesuskaoz15-Jun-11 10:03 
Generalfacing problem in managing users. Pinmembernaseer baloch26-May-11 2:53 
GeneralRe: facing problem in managing users. PinmemberJorge Bay Gondra26-May-11 3:34 
GeneralThis Articles Grate Pinmembernagarajapdotnet23-Dec-10 5:32 
GeneralNot working properly Pinmembershanawazway14-Oct-10 21:41 
Generalsettimeout PinmemberAjay Kale New27-Sep-10 19:46 
GeneralRe: settimeout PinmemberJorge Bay Gondra27-Sep-10 23:15 
GeneralRe: settimeout PinmemberAjay Kale New27-Sep-10 23:25 
GeneralRe: settimeout PinmemberJorge Bay Gondra28-Sep-10 0:56 
GeneralRe: settimeout PinmemberAjay Kale New28-Sep-10 1:45 
GeneralRe: settimeout PinmemberJorge Bay Gondra28-Sep-10 1:53 
GeneralRe: settimeout PinmemberAjay Kale New28-Sep-10 1:59 
GeneralExcellent article! PinmemberRiaan Lehmkuhl17-Feb-10 20:26 
Questionhow to get last 2 hours message? at start? & FireFox Problem PinmemberArny11-Feb-10 20:29 
AnswerRe: how to get last 2 hours message? at start? & FireFox Problem PinmemberJorge Bay Gondra10-Feb-10 6:03 
GeneralRe: how to get last 2 hours message? at start? & FireFox Problem PinmemberArny110-Feb-10 20:09 
GeneralContacto Pinmemberpeterlp20-Jan-10 10:17 
GeneralRe: Contacto PinmemberJorge Bay Gondra10-Feb-10 6:12 
Generaladd css style to the code PinmemberArny114-Dec-09 20:23 
GeneralRe: add css style to the code PinmemberJorge Bay Gondra21-Jan-10 6: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
Web04 | 2.8.141223.1 | Last Updated 24 Feb 2010
Article Copyright 2009 by Jorge Bay Gondra
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid