Sample Code of ASP. NET MVC4 asynchronous chat room and mvc4 sample code

Source: Internet
Author: User

Sample Code of ASP. NET MVC4 asynchronous chat room and mvc4 sample code

This article introduces the sample code of ASP. NET MVC4 asynchronous chat room and shares it with you, as follows:

Class diagram:

Domain Layer

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<IEnumerable<string>, 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<string> GetSince(DateTime since);  }}

ICallbackQueue. cs

using System;using System.Collections.Generic;namespace MvcAsyncChat.Domain{  public interface ICallbackQueue  {    void Enqueue(Action<IEnumerable<string>, DateTime> callback);    IEnumerable<Action<IEnumerable<string>, DateTime>> DequeueAll();    IEnumerable<Action<IEnumerable<string>, 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 implements dateTimeSvc; readonly implements messageRepo; public ChatRoom (ICallbackQueue callbackQueue, implements dateTimeSvc, implements 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 ipant (string name) {AddMessage (string. format ("{0} has entered the room. ", name);} public void GetMessages (DateTime since, Action <IEnumerable <string>, 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<Tuple<string, DateTime>>();    }    public IList<Tuple<string, DateTime>> Messages { get; private set; }    public DateTime Add(string message)    {      var timestamp = DateTime.UtcNow;      Messages.Add(new Tuple<string, DateTime>(message, timestamp));      return timestamp;    }    public IEnumerable<string> 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<Tuple<Action<IEnumerable<string>, DateTime>, DateTime>>();    }    public Queue<Tuple<Action<IEnumerable<string>, DateTime>, DateTime>> Callbacks { get; private set; }    public void Enqueue(Action<IEnumerable<string>, DateTime> callback)    {      Callbacks.Enqueue(new Tuple<Action<IEnumerable<string>, DateTime>, DateTime>(callback, DateTime.UtcNow));    }    public IEnumerable<Action<IEnumerable<string>, DateTime>> DequeueAll()    {      while (Callbacks.Count > 0)        yield return Callbacks.Dequeue().Item1;    }    public IEnumerable<Action<IEnumerable<string>, 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 folder entity class

EnterRequest. cs

Using System; using System. componentModel; using System. componentModel. dataAnnotations; namespace MvcAsyncChat. requestModels {public class EnterRequest {[DisplayName ("name")] [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 folder entity class

GetMessagesResponse. cs

using System;using System.Collections.Generic;namespace MvcAsyncChat.ResponseModels{  public class GetMessagesResponse  {    public string error { get; set; }    public IEnumerable<string> 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 IDateT ImeSvc 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 ActionR Esult EnterRoom (EnterRequest enterRequest) {if (! ModelState. isValid) return View (enterRequest); authSvc. authenticate (enterRequest. name); chatRoom. addParticipant ipant (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. id Entity. Name); return RedirectToRoute (RouteName. Enter);} [HttpPost, Authorize] public ActionResult Say (SayRequest sayRequest) {if (! ModelState. isValid) return Json (new SayResponse () {error = "the request is invalid. "}); chatRoom. addMessage (User. identity. name + "said:" + 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 GetMessagesComp Leted (string error, DateTime? Since, IEnumerable <string> 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("<div class='" + (type || "") + "'>" + message + "</div>")}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 view folder

Enter. cshtml

@ Model MvcAsyncChat. RequestModels. EnterRequest @ {View. Title = "Enter"; Layout = "~ /Views/Shared/_ Layout. cshtml ";}@ section Head {}< tr id =" enterSection "> <td> 

Room. cshtml

@ Using MvcAsyncChat; @ using MvcAsyncChat. RequestModels; @ model SayRequest @ {View. Title = "Room"; Layout = "~ /Views/Shared/_ Layout. cshtml ";} @ section Head {<script src =" @ Url. Content ("~ /Scripts/room. js ") "> </script >}< tr id =" messagesSection "> <td> </tr> <tr id =" actionsSection "> <td> <label = "actionsList"> operation: </label> <ul id = "actionsList"> <li> @ Html. routeLink ("leave room", RouteName. leave) </li> </ul> @ using (Ajax. beginForm ("say", new {}, new AjaxOptions () {OnFailure = "onSayFailed", OnSuccess = "onSay", HttpMethod = "POST ",}, new {id = "sayForm"}) {@ Html. editorForModel () }</td> </tr> @ section PostScript {<script >$ (document ). ready (function () {$ ("# Text "). attr ("placeholder", "you say:"); $ ("# Text "). focus (); setSayHandler (); getMessages () ;}); </script>}

Running result:

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.