2010-03-21 61 views
2

我在我的一个mvc网站上构建了一个ajax聊天。一切工作正常。我正在使用轮询。在特定的时间间隔,我使用$ .post从db获取消息。但有一个问题。使用$ .post检索的消息不断重复。这里是我的JavaScript代码和控制器方法。ASP.NET MVC ajax聊天

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); 
     } 

,这里是我的控制器方法来获取数据:

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()}); 
     } 

一切工作absloutely完美。但我有一些消息重复。第一次加载页面我正在检索数据并调用GetMessages()函数。我正在加载第hdnLastMsgRec第一次加载页面的值,并且此字段的值由javascript设置。

我认为消息因异步调用而不断重复。我不知道,可能你们可以帮我解决这个问题。

或者您可以提出更好的实现方法。

+0

我很好奇你正在使用什么样的投票。 – Ciel 2010-04-19 20:35:01

回答

0

默认情况下$。员额()缓存结果

,您可以调用$ .ajaxSetup({缓存:假});在JS GetMessages函数调用之前确保禁用缓存或将$ .post更改为$ .ajax并将cache属性设置为false。最终$。员额()是一个捷径,这一点:

$.ajax({ 
    type: 'POST', 
    url: url, 
    data: data, 
    success: success 
    dataType: dataType 
}); 
1

Kaivalya是关于缓存正确的,但我也建议你的设计可以并且应该改变只是一点点。

我最近做了一个非常类似的应用程序,我发现我的设计通过让控制器使用相当标准的PRG模式(post-redirect-get)得到了极大的增强。为什么增强?好吧,因为POST方法是为了将东西添加到应用程序而构建的,所以GET方法应该用于获取没有副作用的信息。您的投票应该只是收到新的消息W/O副作用。

因此,而不是你的$ .post调用期望数据和处理回调,我建议让你的控制器公开一个方法,通过POST创建新的聊天消息,然后获得最后的X聊天消息的另一种方法,或自某个时间戳以来的消息。

从post动作的javascript回调,然后可以更新一些变量(例如最后一条消息ID,最后一条消息的时间戳,甚至是基于重定向中包含的信息的下一条消息的整个URL) 。然后,你有(单独)从jquery调用$。get调用,它被设置为poll()函数,就像你说的,全部它的功能是获取最新的聊天消息,它的回调更新聊天界面。

1

我得到了我的答案在这里:ASP.NET AJAX CHAT

下面我指的名字是从上面的链接。

我认为实际的问题是时间戳事件和$ .post的异步行为。在调用“GetMessages()”方法后,即使先前请求检索聊天消息未完成,anathor也会调用相同的方法,因为在$ .post方法之外设置了“GetMessages()”方法的超时时间。在我的问题中,您可以看到“GetMessages()”方法的超时设置在$ .post方法之外。现在我在$ .post方法中设置“GetMessages()”方法的超时时间。因此下一次对“GetMessages()”的调用仅在当前$ .post方法完成3秒后才会发生。我已经发布了下面的代码。

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.LastMsgRec.length != 0) 
        $("#hdnLastMsgRec").val(Data.LastMsgRec); 
       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 { 
       } 
       t = setTimeout("GetMessages()", 3000); 
      }, "json"); 

     } 

除此之外,我也改变了一些东西。正如ignatandrei所建议的,我放置$(“#hdnLastMsgRec”).val(Data.LastMsgRec);函数(Data){。

并且还

通过MikeSW所述我改变了数据检索过程。之前,我是基于时间跨度提取数据(检索与此号码的 相关的所有数据,这些数据的时间间隔比上次检索到的消息时间跨度的时间更长),但现在我跟踪messageid。现在我只检索那些 的消息ID大于上次检索到的消息ID的数据。

猜猜我的Intranet上到目前为止还没有重复和完美工作的聊天应用程序。

我仍然看到它的性能,当部署在互联网上。

我认为它解决了我的问题。

我仍然会测试系统,让你们知道是否有任何问题。