2010-03-21 167 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上到目前爲止還沒有重複和完美工作的聊天應用程序。

我仍然看到它的性能,當部署在互聯網上。

我認爲它解決了我的問題。

我仍然會測試系統,讓你們知道是否有任何問題。