I built an ajax chat in one of my mvc website. everything is working fine. I am using polling. At certain interval i am using $.post to get the messages from the db. But there is a problem. The message retrieved using $.post keeps on repeating. here is my
javascript code and controller method.
javascript method:
var t;
function GetMessages() {
var LastMsgRec = $("#hdnLastMsgRec").val();
var RoomId = $("#hdnRoomId").val();
//Get all the messages associated with this roomId
$.post("/Chat/GetMessages", { roomId: RoomId, lastRecMsg: LastMsgRec }, function(Data) {
if (Data.Messages.length != 0) {
$("#messagesCont").append(Data.Messages);
if (Data.newUser.length != 0)
$("#usersUl").append(Data.newUser);
$("#messagesCont").attr({ scrollTop: $("#messagesCont").attr("scrollHeight") - $('#messagesCont').height() });
$("#userListCont").attr({ scrollTop: $("#userListCont").attr("scrollHeight") - $('#userListCont').height() });
}
else {
}
$("#hdnLastMsgRec").val(Data.LastMsgRec);
}, "json");
Everything is working absloutely perfect. But i some messages getting repeated. The first time page loads i am retrieving the data and call GetMessages() function. I am loading the value of field
hdnLastMsgRec the first time page loads and after the value for this field are set by the javascript.
I think the message keeps on repeating because of asynchronous calls. I don't know, may be you guys can help me solve this.
I'm doing almost the same thing with my chat, keeping the last message id and requesting only what's above it. Sometimes I get a repetition but it appears only to the user who just sent a new message. The others don't see it and I'm guessing it's a js issue.
However it doesn't appear very often so it's not a problem. I'm using jQuery templates to inject the json into html.
In your case, does duplication appear only when you retrieve the messages?
i think the actual problem was with the timestamp thing and asynchronous behaviour of $.post. after calling "GetMessages()" method, even if the previous request to retrive chat message was not complete anathor call to same method used to fire due to setting
timeout for "GetMessages()" method outside the $.post method. In my question you can see that timeout for "GetMessages()" method is set outside the $.post method. Now i set the timeout for "GetMessages()" method inside the $.post method. so that next call
to "GetMessages()" only occur after 3 seconds of completion of current $.post method. I have posted the code below.
I addition to that i also changed few things.
As suggested by ignatandrei i placed $("#hdnLastMsgRec").val(Data.LastMsgRec);
immediately after function(Data) {.
The chat I've talked about is functional over internet (part of the game from my sig) and it works quite well (aside that seldom duplication message when you send it). I'm also caching the last 50 mesages or so in memory so retrieval is very fast. You can
see it in action at @XemerysDen (twitter) since the chat can be followed on twitter as well :)
nccsbim071
Member
24 Points
44 Posts
ASP.NET MVC CHAT
Mar 21, 2010 09:23 AM|LINK
I built an ajax chat in one of my mvc website. everything is working fine. I am using polling. At certain interval i am using $.post to get the messages from the db. But there is a problem. The message retrieved using $.post keeps on repeating. here is my javascript code and controller method.
javascript method:
var t;
function GetMessages() {
var LastMsgRec = $("#hdnLastMsgRec").val();
var RoomId = $("#hdnRoomId").val();
//Get all the messages associated with this roomId
$.post("/Chat/GetMessages", { roomId: RoomId, lastRecMsg: LastMsgRec }, function(Data) {
if (Data.Messages.length != 0) {
$("#messagesCont").append(Data.Messages);
if (Data.newUser.length != 0)
$("#usersUl").append(Data.newUser);
$("#messagesCont").attr({ scrollTop: $("#messagesCont").attr("scrollHeight") - $('#messagesCont').height() });
$("#userListCont").attr({ scrollTop: $("#userListCont").attr("scrollHeight") - $('#userListCont').height() });
}
else {
}
$("#hdnLastMsgRec").val(Data.LastMsgRec);
}, "json");
t = setTimeout("GetMessages()", 3000);
}
Controller method:
public JsonResult GetMessages(int roomId,DateTime lastRecMsg) { StringBuilder messagesSb = new StringBuilder(); StringBuilder newUserSb = new StringBuilder(); List<Message> msgs = (dc.Messages).Where(m => m.RoomID == roomId && m.TimeStamp > lastRecMsg).ToList(); if (msgs.Count == 0) { return Json(new { Messages = "", LastMsgRec = System.DateTime.Now.ToString() }); } foreach (Message item in msgs) { messagesSb.Append(string.Format(messageTemplate,item.User.Username,item.Text)); if (item.Text == "Just logged in!") newUserSb.Append(string.Format(newUserTemplate,item.User.Username)); } return Json(new {Messages = messagesSb.ToString(),LastMsgRec = System.DateTime.Now.ToString(),newUser = newUserSb.ToString().Length == 0 ?"":newUserSb.ToString()}); }Everything is working absloutely perfect. But i some messages getting repeated. The first time page loads i am retrieving the data and call GetMessages() function. I am loading the value of field hdnLastMsgRec the first time page loads and after the value for this field are set by the javascript.
I think the message keeps on repeating because of asynchronous calls. I don't know, may be you guys can help me solve this.
or you can suggest better way to implement this.
asp.net mvc ajax chat
ignatandrei
All-Star
137682 Points
22147 Posts
Moderator
MVP
Re: ASP.NET MVC CHAT
Mar 21, 2010 08:24 PM|LINK
put this
immediately after
and tell the results!
MikeSW
Member
693 Points
121 Posts
Re: ASP.NET MVC CHAT
Mar 21, 2010 08:35 PM|LINK
I'm doing almost the same thing with my chat, keeping the last message id and requesting only what's above it. Sometimes I get a repetition but it appears only to the user who just sent a new message. The others don't see it and I'm guessing it's a js issue. However it doesn't appear very often so it's not a problem. I'm using jQuery templates to inject the json into html.
In your case, does duplication appear only when you retrieve the messages?
PortfolioEngine.Net - Showcase your work in a meaningful way
bradwils
Contributor
5779 Points
691 Posts
Microsoft
Re: ASP.NET MVC CHAT
Mar 21, 2010 10:13 PM|LINK
Browsers will cache JSON just the same as they'll cache HTML, so make sure you're disabling browser caching in your JSON handlers.
nccsbim071
Member
24 Points
44 Posts
Re: ASP.NET MVC CHAT
Mar 22, 2010 07:49 AM|LINK
thanks of the reply guys.
i think the actual problem was with the timestamp thing and asynchronous behaviour of $.post. after calling "GetMessages()" method, even if the previous request to retrive chat message was not complete anathor call to same method used to fire due to setting timeout for "GetMessages()" method outside the $.post method. In my question you can see that timeout for "GetMessages()" method is set outside the $.post method. Now i set the timeout for "GetMessages()" method inside the $.post method. so that next call to "GetMessages()" only occur after 3 seconds of completion of current $.post method. I have posted the code below.
asp.net mvc ajax chat
MikeSW
Member
693 Points
121 Posts
Re: ASP.NET MVC CHAT
Mar 22, 2010 07:57 AM|LINK
The chat I've talked about is functional over internet (part of the game from my sig) and it works quite well (aside that seldom duplication message when you send it). I'm also caching the last 50 mesages or so in memory so retrieval is very fast. You can see it in action at @XemerysDen (twitter) since the chat can be followed on twitter as well :)
PortfolioEngine.Net - Showcase your work in a meaningful way
nccsbim071
Member
24 Points
44 Posts
Re: ASP.NET MVC CHAT
Mar 22, 2010 08:03 AM|LINK
Hi,
MikeSW
I don't know much about the caching the data in memory and then retrieving the data from cache. Can you please explain
bit so that i can also implement it in my chat application.
MikeSW
Member
693 Points
121 Posts
Re: ASP.NET MVC CHAT
Mar 22, 2010 08:25 AM|LINK
I have a chat "server" object which stays static and handles the mesages. Very simplistic and does the job.
public class ChatServer:IChatServer { private IChatStorage _storage; List<IChatMessage> _list; public ChatServer(IChatStorage repo) { _storage = repo; } private object Sync { get { return ((IList) List).SyncRoot; } } public void Add(int user, string message) { if (string.IsNullOrEmpty(message.Trim())) return; if (message.Length > 250) message = message.Substring(0, 250); var msg = new ChatMessage(user, message); _storage.SaveMessage(msg); lock(Sync) { _list.Add(msg); if (_list.Count >= 75) { _list.RemoveRange(0, 25); } } return; } List<IChatMessage> List { get { if (_list==null) { _list= new List<IChatMessage>(1); _list.AddRange(_storage.GetLastMessages(50).OrderBy(d=>d.Id)); } return _list; } } public IEnumerable<IChatMessage> AllMessages { get { return List; } } public IEnumerable<IChatMessage> GetUpdates(int id) { return List.Where(d => d.Id > id).OrderByDescending(d=>d.Id); } }mvc chat
PortfolioEngine.Net - Showcase your work in a meaningful way
nccsbim071
Member
24 Points
44 Posts
Re: ASP.NET MVC CHAT
Mar 22, 2010 08:35 AM|LINK
thanks for the reply mike. I will try to implement it.