ASP.NET MVC ajax чат - PullRequest
       7

ASP.NET MVC ajax чат

2 голосов
/ 21 марта 2010

Я создал чат ajax на одном из моих веб-сайтов mvc. все работает нормально. Я использую опрос. Через определенный интервал я использую $ .post для получения сообщений из БД. Но есть проблема. Сообщение, полученное с помощью $ .post, продолжает повторяться. Вот мой код JavaScript и метод контроллера.

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

Все работает абсолютно идеально. Но некоторые сообщения повторяются. При первой загрузке страницы я получаю данные и вызываю функцию GetMessages (). Я загружаю значение поля hdnLastMsgRec при первой загрузке страницы и после того, как значение для этого поля установлено в JavaScript.

Я думаю, что сообщение продолжает повторяться из-за асинхронных вызовов. Я не знаю, может быть, вы, ребята, можете помочь мне решить эту проблему.

или вы можете предложить лучший способ реализации этого.

Ответы [ 3 ]

1 голос
/ 21 марта 2010

Кайвалья верно относится к кешированию, но я бы также предположил, что ваш дизайн может и должен быть изменен лишь чуть-чуть.

Недавно я сделал очень похожее приложение, и обнаружил, что мой дизайн был значительно улучшен, позволяя контроллерам работать с довольно стандартным шаблоном PRG (post-redirect-get). Почему улучшено? хорошо, поскольку методы POST создаются для добавления чего-либо в приложение, предполагается, что методы GET используются для получения информации без побочных эффектов. Ваш опрос должен просто получать новые сообщения без побочных эффектов.

Поэтому вместо того, чтобы ваш вызов $ .post ожидал данных и обрабатывал обратный вызов, я бы порекомендовал вашему контроллеру предоставить метод для создания новых сообщений чата через POST, а затем другой метод, который получает последние сообщения X-чата, или сообщения с определенной временной отметки или чего-то еще.

Обратный вызов javascript из действия post затем может обновить некоторые переменные (например, идентификатор последнего сообщения, метку времени последнего сообщения или даже весь URL-адрес следующего сообщения на основе информации, содержащейся в перенаправлении, что угодно).

$ .post будет запускаться только в ответ на пользовательский ввод (например, введите поле, нажмите «отправить»). Затем у вас есть (отдельно) вызов $ .get из jquery, настроенный для опроса типа вы сказали, и все получает только последние сообщения чата, а обратный вызов обновляет интерфейс чата вместе с ними.

1 голос
/ 22 марта 2010

Я получил ответ здесь: ASP.NET AJAX CHAT

Имена ниже, на которые я ссылаюсь, являются ссылками сверху.

Я думаю, что настоящая проблема былас отметкой времени и асинхронным поведением $ .post.после вызова метода «GetMessages ()», даже если предыдущий запрос на получение сообщения чата не был завершен, вызов anathor к тому же методу, который использовался для запуска, из-за установки времени ожидания для метода «GetMessages ()» вне метода $ .post.В моем вопросе вы можете видеть, что время ожидания для метода "GetMessages ()" установлено вне метода $ .post.Теперь я установил тайм-аут для метода «GetMessages ()» внутри метода $ .post.так что следующий вызов GetMessages () произойдет только через 3 секунды после завершения текущего метода $ .post.Я разместил код ниже.

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);сразу после функции (Данные) {.

, а также

, как сказал MikeSW, я изменил процесс поиска данных.Ранее я извлекал данные на основе временного промежутка (извлекал все данные, связанные с этим идентификатором комнаты, который имеет больший временной промежуток, чем последний раз извлеченные данные полученного сообщения), но теперь я отслеживаю идентификатор сообщения.Теперь я извлекаю только те данные, у которых идентификатор сообщения больше, чем у последнего извлеченного идентификатора сообщения.

и думаю, что в моем интранете пока нет повторяющихся и отлично работающих приложений чата.

Я все еще должен видеть его производительность при развертывании в Интернете.

Я думаю, что это решило мою проблему.

Я все еще буду тестировать систему и сообщу вам, если есть какие-либопроблема.

0 голосов
/ 21 марта 2010

По умолчанию $ .post () кэширует результаты

Вы можете вызвать $ .ajaxSetup ({cache: false}); перед вызовом функции JS GetMessages, чтобы убедиться, что кэширование отключено, или измените $ .post на $ .ajax и установите для атрибута cache значение false. В конце $ .post () это короткий путь к этому:

$.ajax({
  type: 'POST',
  url: url,
  data: data,
  success: success
  dataType: dataType
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...