本文介绍了ASP.NET 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 System.ComponentModel;

using System.ComponentModel.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 System.ComponentModel;

using System.ComponentModel.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聊天]是使用ASP.NET MVC 3的异步聊天室

进入聊天室

@using(Html.BeginForm()) {

@Html.EditorForModel()

}

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

});

}

运行结果如图:

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

asp.net ajax聊天室,ASP.NET MVC4异步聊天室的示例代码相关推荐

  1. 《ASP.NET AJAX程序设计 第I卷 服务器端ASP.NET AJAX Extensions与ASP.NET AJAX Control Toolkit》目录(最终定稿)...

    第一二卷都比较简单,特别是第一卷,讲的都是服务器端控件.第二卷是客户端部分,第三卷是高级内容,包括调试.性能.部署.控件开发.源代码结构.用户体验.心理学模型等等-- 第一卷争取在四月份出版,谢谢各位 ...

  2. asp.net ajax删除数据,Asp.net MVC 2 使用Ajax删除数据

    一.新建一个Asp.net MVC 2 Empty Web Application. 二.添加一个名叫DataClasses1.dbml的Model,拖放Student表,最后如下图所示. 三.添加一 ...

  3. asp.net ajax 源码,asp.net+jquery+ajax简单留言板 v1.2

    asp.netC#+jquery1.4.1 +ajax留言板程序说明 采用asp.net C#+ jquery1.4.1 +ajax的实现 主要用aspx文件请求 还可以用ashx处理 ajax返回类 ...

  4. MSDN Webcast“深入浅出ASP.NET AJAX系列”

    课程: ASP.NET AJAX深入浅出系列课程(1):ASP.NET AJAX 概述(3月13日):对于ASP.NET AJAX的大致功能进行概述和演示,通过简单的演示让听众了解到ASP.NET A ...

  5. SharePoint 2010中的客户端AJAX应用——ASP.NET AJAX模板

    WCF Data Services是SharePoint 2010中一个极具吸引力的新特性.然而,因为它的强大,直接对其进行编程仍然会有点痛苦.幸运的是,一个新的相关技术 -- ASP.Net AJA ...

  6. ASP.NET之父谈ASP.NET AJAX

    ASP.NET之父SCOTT GUTHRIE强烈推荐的ASP.NET AJAX著作 世界各地数百万专业开发人员每天都在使用ASP.NET.全世界最成功的一些网站和应用都以它为后盾,每天还有成千上万的新 ...

  7. ASP.NET AJAX入门系列(1):概述

    经常关注我的Blog的朋友可能注意到了,在我Blog的左边系列文章中,已经移除了对Atlas学习手记系列文章的推荐,因为随着ASP.NET AJAX 1.0 Beta版的发布,它们已经不再适用,为了不 ...

  8. Msdn 杂志 asp.net ajax 文章汇集

    asp.net ajax 充分利用客户端 JavaScript.DHTML 和 XMLHttpRequest 对象.其目的是帮助开发人员创建更具交互性的支持 AJAX 的 Web 应用程序 ASP.N ...

  9. [翻译]ASP.NET AJAX与SharePoint的集成

    原文: Integrating ASP.NET AJAX with SharePoint 来自微软SharePoint Team Blog Microsoft ASP.NET AJAX 1.0: 一点 ...

最新文章

  1. malloc和new出来的地址都是虚拟地址 你就说内存管理单元怎么可能让你直接操作硬件内存地址!...
  2. gunicorn之日志详细配置
  3. 【教程】超详细的虚拟无线控制器安装教程
  4. 网银无法登录解决办法
  5. java 中导出word后压缩文件_Java批量导出word压缩后的zip文件案例
  6. Machine Learning Mastery 博客文章翻译:深度学习与 Keras
  7. 虚拟机Ubuntu20.04.2LTS卸载python3.8出现tty1-tty6循环登录,无法进入图形化界面,乱码(亲测)
  8. SVM原理以及Tensorflow 实现SVM分类(附代码)
  9. 2021牛客暑期多校训练营3,签到题BEFJ
  10. 软件需求工程与UML建模第十二周作业
  11. HTML超连接(a标记)
  12. Q 语言 -- 赋值表达式
  13. 罗永浩写给俞敏洪的信
  14. QT图形显示和处理6
  15. 第7章概率和样本:样本均值的分布
  16. 淘宝/天猫关键词搜索采集接口分析商品价格走势(商品列表,商品销量,商品价格,分类ID采集精准商品数据)接口代码对接流程
  17. SK-learn实现k近邻算法【准确率随k值的变化】-------莺尾花种类预测
  18. 基于百度AI平台的植物识别系统 新手适用!!
  19. 左右两侧浮动广告代码
  20. IOS单例模式及单例模式的优缺点

热门文章

  1. 华为提出十大数学挑战!解出一个就是年薪百万!
  2. 每日一皮:程序员穿着图解析
  3. Spring Boot 2.x基础教程:使用JdbcTemplate访问MySQL数据库
  4. MySQL百万级数据分页查询及优化
  5. 死磕Java并发:J.U.C之阻塞队列:PriorityBlockingQueue
  6. Spring Cloud实战小贴士:Ribbon的饥饿加载(eager-load)模式
  7. 都在说微服务,那么微服务的反模式和陷阱是什么(三)
  8. mysql导出停机_MySQL自动停机的问题处理实战记录
  9. asp.net oracle优化,[转]ASP.NET性能优化
  10. insightface mxnet训练 out of Memory