1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > asp.net ajax聊天室 ASP.NET MVC4异步聊天室的示例代码

asp.net ajax聊天室 ASP.NET MVC4异步聊天室的示例代码

时间:2023-07-02 22:19:10

相关推荐

asp.net ajax聊天室 ASP.NET MVC4异步聊天室的示例代码

本文介绍了 MVC4异步聊天室的示例代码,分享给大家,具体如下:

类图:

Domain层

IChatRoom.cs

using System;

using System.Collections.Generic;

namespace MvcAsyncChat.Domain

{

public interface IChatRoom

{

void AddMessage(string message);

void AddParticipant(string name);

void GetMessages(

DateTime since,

Action, DateTime> callback);

void RemoveParticipant(string name);

}

}

IMessageRepo.cs

using System;

using System.Collections.Generic;

namespace MvcAsyncChat.Domain

{

public interface IMessageRepo

{

DateTime Add(string message);

IEnumerable GetSince(DateTime since);

}

}

ICallbackQueue.cs

using System;

using System.Collections.Generic;

namespace MvcAsyncChat.Domain

{

public interface ICallbackQueue

{

void Enqueue(Action, DateTime> callback);

IEnumerable, DateTime>> DequeueAll();

IEnumerable, DateTime>> DequeueExpired(DateTime expiry);

}

}

ChatRoom.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading;

using MvcAsyncChat.Svcs;

namespace MvcAsyncChat.Domain

{

public class ChatRoom : IChatRoom

{

readonly ICallbackQueue callbackQueue;

readonly IDateTimeSvc dateTimeSvc;

readonly IMessageRepo messageRepo;

public ChatRoom(

ICallbackQueue callbackQueue,

IDateTimeSvc dateTimeSvc,

IMessageRepo messageRepo)

{

this.callbackQueue = callbackQueue;

this.dateTimeSvc = dateTimeSvc;

this.messageRepo = messageRepo;

}

public void AddMessage(string message)

{

var timestamp = messageRepo.Add(message);

foreach (var callback in callbackQueue.DequeueAll())

callback(new[] { message }, timestamp);

}

public void AddParticipant(string name)

{

AddMessage(string.Format("{0} 已进入房间.", name));

}

public void GetMessages(

DateTime since,

Action, DateTime> callback)

{

var messages = messageRepo.GetSince(since);

if (messages.Count() > 0)

callback(messages, since);

else

callbackQueue.Enqueue(callback);

}

public void RemoveParticipant(string name)

{

AddMessage(string.Format("{0} left the room.", name));

}

}

}

InMemMessageRepo.cs

using System;

using System.Collections.Generic;

using System.Linq;

namespace MvcAsyncChat.Domain

{

public class InMemMessageRepo : IMessageRepo

{

public InMemMessageRepo()

{

Messages = new List>();

}

public IList> Messages { get; private set; }

public DateTime Add(string message)

{

var timestamp = DateTime.UtcNow;

Messages.Add(new Tuple(message, timestamp));

return timestamp;

}

public IEnumerable GetSince(DateTime since)

{

return Messages

.Where(x => x.Item2 > since)

.Select(x => x.Item1);

}

}

}

CallbackQueue.cs

using System;

using System.Collections.Generic;

using System.Linq;

namespace MvcAsyncChat.Domain

{

public class CallbackQueue : ICallbackQueue

{

public CallbackQueue()

{

Callbacks = new Queue, DateTime>, DateTime>>();

}

public Queue, DateTime>, DateTime>> Callbacks { get; private set; }

public void Enqueue(Action, DateTime> callback)

{

Callbacks.Enqueue(new Tuple, DateTime>, DateTime>(callback, DateTime.UtcNow));

}

public IEnumerable, DateTime>> DequeueAll()

{

while (Callbacks.Count > 0)

yield return Callbacks.Dequeue().Item1;

}

public IEnumerable, DateTime>> DequeueExpired(DateTime expiry)

{

if (Callbacks.Count == 0)

yield break;

var oldest = Callbacks.Peek();

while (Callbacks.Count > 0 && oldest.Item2 <= expiry)

{

yield return Callbacks.Dequeue().Item1;

if (Callbacks.Count > 0)

oldest = Callbacks.Peek();

}

}

}

}

RequestModels文件夹实体类

EnterRequest.cs

using System;

using ponentModel;

using ponentModel.DataAnnotations;

namespace MvcAsyncChat.RequestModels

{

public class EnterRequest

{

[DisplayName("名称")]

[Required, StringLength(16), RegularExpression(@"^[A-Za-z0-9_\ -]+$", ErrorMessage="A name must be alpha-numeric.")]

public string Name { get; set; }

}

}

GetMessagesRequest.cs

using System;

namespace MvcAsyncChat.RequestModels

{

public class GetMessagesRequest

{

public string since { get; set; }

}

}

SayRequest.cs

using System;

using ponentModel;

using ponentModel.DataAnnotations;

namespace MvcAsyncChat.RequestModels

{

public class SayRequest

{

[Required, StringLength(1024), DataType(DataType.MultilineText)]

public string Text { get; set; }

}

}

ResponseModels文件夹实体类

GetMessagesResponse.cs

using System;

using System.Collections.Generic;

namespace MvcAsyncChat.ResponseModels

{

public class GetMessagesResponse

{

public string error { get; set; }

public IEnumerable messages { get; set; }

public string since { get; set; }

}

}

SayResponse.cs

using System;

namespace MvcAsyncChat.ResponseModels

{

public class SayResponse

{

public string error { get; set; }

}

}

ChatController.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Mvc.Async;

using MvcAsyncChat.Domain;

using MvcAsyncChat.RequestModels;

using MvcAsyncChat.ResponseModels;

using MvcAsyncChat.Svcs;

namespace MvcAsyncChat.Controllers

{

public class ChatController : AsyncController

{

readonly IAuthSvc authSvc;

readonly IChatRoom chatRoom;

readonly IDateTimeSvc dateTimeSvc;

public ChatController(

IAuthSvc authSvc,

IChatRoom chatRoom,

IDateTimeSvc dateTimeSvc)

{

this.authSvc = authSvc;

this.chatRoom = chatRoom;

this.dateTimeSvc = dateTimeSvc;

}

[ActionName("enter"), HttpGet]

public ActionResult ShowEnterForm()

{

if (User.Identity.IsAuthenticated)

return RedirectToRoute(RouteName.Room);

return View();

}

[ActionName("enter"), HttpPost]

public ActionResult EnterRoom(EnterRequest enterRequest)

{

if (!ModelState.IsValid)

return View(enterRequest);

authSvc.Authenticate(enterRequest.Name);

chatRoom.AddParticipant(enterRequest.Name);

return RedirectToRoute(RouteName.Room);

}

[ActionName("room"), HttpGet, Authorize]

public ActionResult ShowRoom()

{

return View();

}

[ActionName("leave"), HttpGet, Authorize]

public ActionResult LeaveRoom()

{

authSvc.Unauthenticate();

chatRoom.RemoveParticipant(User.Identity.Name);

return RedirectToRoute(RouteName.Enter);

}

[HttpPost, Authorize]

public ActionResult Say(SayRequest sayRequest)

{

if (!ModelState.IsValid)

return Json(new SayResponse() { error = "该请求无效." });

chatRoom.AddMessage(User.Identity.Name+" 说:"+sayRequest.Text);

return Json(new SayResponse());

}

[ActionName("messages"), HttpPost, Authorize]

public void GetMessagesAsync(GetMessagesRequest getMessagesRequest)

{

AsyncManager.OutstandingOperations.Increment();

if (!ModelState.IsValid)

{

AsyncManager.Parameters["error"] = "The messages request was invalid.";

AsyncManager.Parameters["since"] = null;

AsyncManager.Parameters["messages"] = null;

AsyncManager.OutstandingOperations.Decrement();

return;

}

var since = dateTimeSvc.GetCurrentDateTimeAsUtc();

if (!string.IsNullOrEmpty(getMessagesRequest.since))

since = DateTime.Parse(getMessagesRequest.since).ToUniversalTime();

chatRoom.GetMessages(since, (newMessages, timestamp) =>

{

AsyncManager.Parameters["error"] = null;

AsyncManager.Parameters["since"] = timestamp;

AsyncManager.Parameters["messages"] = newMessages;

AsyncManager.OutstandingOperations.Decrement();

});

}

public ActionResult GetMessagesCompleted(

string error,

DateTime? since,

IEnumerable messages)

{

if (!string.IsNullOrWhiteSpace(error))

return Json(new GetMessagesResponse() { error = error });

var data = new GetMessagesResponse();

data.since = since.Value.ToString("o");

data.messages = messages;

return Json(data);

}

}

}

room.js

var since = "",

errorCount = 0,

MAX_ERRORS = 6;

function addMessage(message, type) {

$("#messagesSection > td").append("

" + message + "")

}

function showError(error) {

addMessage(error.toString(), "error");

}

function onSayFailed(XMLHttpRequest, textStatus, errorThrown) {

showError("An unanticipated error occured during the say request: " + textStatus + "; " + errorThrown);

}

function onSay(data) {

if (data.error) {

showError("An error occurred while trying to say your message: " + data.error);

return;

}

}

function setSayHandler() {

$("#Text").keypress(function (e) {

if (e.keyCode == 13) {

$("#sayForm").submit();

$("#Text").val("");

return false;

}

});

}

function retryGetMessages() {

if (++errorCount > MAX_ERRORS) {

showError("There have been too many errors. Please leave the chat room and re-enter.");

}

else {

setTimeout(function () {

getMessages();

}, Math.pow(2, errorCount) * 1000);

}

}

function onMessagesFailed(XMLHttpRequest, textStatus, errorThrown) {

showError("An unanticipated error occured during the messages request: " + textStatus + "; " + errorThrown);

retryGetMessages();

}

function onMessages(data, textStatus, XMLHttpRequest) {

if (data.error) {

showError("An error occurred while trying to get messages: " + data.error);

retryGetMessages();

return;

}

errorCount = 0;

since = data.since;

for (var n = 0; n < data.messages.length; n++)

addMessage(data.messages[n]);

setTimeout(function () {

getMessages();

}, 0);

}

function getMessages() {

$.ajax({

cache: false,

type: "POST",

dataType: "json",

url: "/messages",

data: { since: since },

error: onMessagesFailed,

success: onMessages,

timeout: 100000

});

}

Chat视图文件夹

Enter.cshtml

@model MvcAsyncChat.RequestModels.EnterRequest

@{

View.Title = "Enter";

Layout = "~/Views/Shared/_Layout.cshtml";

}

@section Head {}

[MVC聊天]是使用 MVC 3的异步聊天室

@section PostScript {

$(document).ready(function() {

$("#Name").focus();

});

}

Room.cshtml

@using MvcAsyncChat;

@using MvcAsyncChat.RequestModels;

@model SayRequest

@{

View.Title = "Room";

Layout = "~/Views/Shared/_Layout.cshtml";

}

@section Head {

}

操作:

@Html.RouteLink("离开房间", RouteName.Leave)

@using (Ajax.BeginForm("say", new { }, new AjaxOptions() {

OnFailure = "onSayFailed",

OnSuccess = "onSay",

HttpMethod = "POST", }, new { id = "sayForm"})) {

@Html.EditorForModel()

}

@section PostScript {

$(document).ready(function() {

$("#Text").attr("placeholder", "你说:");

$("#Text").focus();

setSayHandler();

getMessages();

});

}

运行结果如图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。