Создание чата на AJAX и jQuery. Часть 1

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 31.10.2015

Рассмотрим более сложный пример применения AJAX в ASP.NET MVC, который представляет создание простенького чата с помощью jQuery. (Готовый проект доступен по ссылке Чат на ASP.NET MVC)

Для начала определим модель, которую мы будем использовать:

public class ChatModel
{
    public List<ChatUser> Users;  // Все пользователи чата

    public List<ChatMessage> Messages; // все сообщения

    public ChatModel()
    {
        Users = new List<ChatUser>();
        Messages = new List<ChatMessage>();

        Messages.Add(new ChatMessage()
        {
            Text = "Чат запущен " + DateTime.Now
        });
    }
}
public class ChatUser
{
    public string Name;
    public DateTime LoginTime;
    public DateTime LastPing;
}

public class ChatMessage
{
    // автор сообщения, если null - автор сервер
    public ChatUser User;
    // время сообщения
    public DateTime Date = DateTime.Now;
    // текст сообщения
    public string Text = "";
}

Модель чата - ChatModel использует для хранения сообщений и пользователей две дополнительные модели ChatMessage и ChatUser.

Теперь перейдем к контроллеру. В проекте MVC 5 уже есть контроллер HomeController по умолчанию. Изменим его следующим способом:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AjaxChat.Models;

namespace AjaxChat.Controllers
{
    public class HomeController : Controller
    {
        static ChatModel chatModel;

        public ActionResult Index(string user, bool? logOn, bool? logOff, string chatMessage)
        {
            try
            {
                if (chatModel == null) chatModel = new ChatModel();

                //оставляем только последние 10 сообщений
                if (chatModel.Messages.Count > 100)
                    chatModel.Messages.RemoveRange(0, 90);

                // если обычный запрос, просто возвращаем представление
                if (!Request.IsAjaxRequest())
                {
                    return View(chatModel);
                }
				// если передан параметр logOn
                else if (logOn != null && (bool)logOn)
                {
                    //проверяем, существует ли уже такой пользователь
                    if (chatModel.Users.FirstOrDefault(u => u.Name == user) != null)
                    {
                        throw new Exception("Пользователь с таким ником уже существует");
                    }
                    else if (chatModel.Users.Count > 10)
                    {
                        throw new Exception("Чат заполнен");
                    }
                    else
                    {
                        // добавляем в список нового пользователя
                        chatModel.Users.Add(new ChatUser()
                        {
                            Name = user,
                            LoginTime = DateTime.Now,
                            LastPing = DateTime.Now
                        });

                        // добавляем в список сообщений сообщение о новом пользователе
                        chatModel.Messages.Add(new ChatMessage()
                        {
                            Text = user + " вошел в чат",
                            Date = DateTime.Now
                        });
                    }

                    return PartialView("ChatRoom", chatModel);
                }
				// если передан параметр logOff
                else if (logOff != null && (bool)logOff)
                {
                    LogOff(chatModel.Users.FirstOrDefault(u => u.Name == user));
                    return PartialView("ChatRoom", chatModel);
                }
                else
                {
                    ChatUser currentUser = chatModel.Users.FirstOrDefault(u => u.Name == user);

                    //для каждлого пользователя запоминаем воемя последнего обновления
                    currentUser.LastPing = DateTime.Now;

                    // удаляем неавтивных пользователей, если время простоя больше 15 сек
                    List<ChatUser> toRemove = new List<ChatUser>();
                    foreach (Models.ChatUser usr in chatModel.Users)
                    {
                        TimeSpan span = DateTime.Now - usr.LastPing;
                        if (span.TotalSeconds > 15)
                            toRemove.Add(usr);
                    }
                    foreach (ChatUser u in toRemove)
                    {
                        LogOff(u);
                    }

                    // добавляем в список сообщений новое сообщение
                    if (!string.IsNullOrEmpty(chatMessage))
                    {
                        chatModel.Messages.Add(new ChatMessage()
                        {
                            User = currentUser,
                            Text = chatMessage,
                            Date = DateTime.Now
                        });
                    }

                    return PartialView("History", chatModel);
                }
            }
            catch (Exception ex)
            {
                //в случае ошибки посылаем статусный код 500
                Response.StatusCode = 500;
                return Content(ex.Message);
            }
        }

        // при выходе пользователя удаляем его из списка
        public void LogOff(ChatUser user)
        {
            chatModel.Users.Remove(user);
            chatModel.Messages.Add(new ChatMessage()
            {
                Text = user.Name + " покинул чат.",
                Date = DateTime.Now
            });
        }
    }
}

Все данные - пользователи и их сообщения будут храниться в переменной chatModel. И так как она будет общим для всех пользователей, она объявлена статической.

Метод Index принимает четыре параметра. Первый параметр идентифицирует пользователя. Параметр logOn при значении true указывает, что пользователь осуществил вход. Параметр logOff при значении true, наоборот, указывает, что пользователь вышел из чата. И последний параметр содержит сообщение пользователя. И в зависимости от значений параметров возвращаем либо обычное представление Index.cshtml, либо одно из частичных представлений.

Если запрос не является AJAX-запросом, передается обычное представление. Если установлен параметр logOn или logOff, то возвращаем частичное представление ChatRoom. И если установлен последний параметр с сообщением пользователя? то возвращается частичное представление History

Теперь определим все эти представления.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850