基于Redis的ASP.NET与js(AJAX)的聊天程序[js长连接][伪推送]

来源:互联网 发布:alphabeta算法 编辑:程序博客网 时间:2024/05/21 09:01

首先是安装Redis, 此处略过n步...


然后,新建一个ASP.NET的MVC2的工程《MvcMessage》,需要下载ServiceStack.Redis并把dll复制到工程下,并正确引用。


好,下面开始贴代码了:

1. 在工程目录《Models》下新建类:Message.cs

using System;using System.Collections.Generic;using System.ComponentModel;using System.ComponentModel.DataAnnotations;using System.Globalization;using System.Linq;using System.Web;using System.Web.Mvc;using System.Web.Security;namespace MvcMessage.Models{    //model    public class Message    {        public long Id { get; set; }        public string SendName { get; set; }        public string SendTo { get; set; }        public DateTime SendTime { get; set; }        public string Msg { get; set; }        public int SendType { get; set; }    }}

2. 在工程目录《Controllers》下新建控制器:MessageController.cs

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using System.Threading;using ServiceStack.Redis;using MvcMessage.Models;namespace MvcMessage.Controllers{    public class MessageController : AsyncController    {        static private Mutex mutex = new Mutex();//不了解的可以去看资料,这里不说了        static RedisClient redisClient = new RedisClient("172.18.1.240");//redis的IP,端口默认的则不用写        public ActionResult Index()        {            return View();        }        public void SendMessageAsync()        {            mutex.WaitOne();            try            {                using (var msgs = redisClient.GetTypedClient<Message>())//Redis消息对象                {                    var m = new Message                    {                        Id = msgs.GetNextSequence(),                        Msg = HttpContext.Request["msg"],                        SendTime = Convert.ToDateTime(HttpContext.Request["time"]),                        SendType = Convert.ToInt32(HttpContext.Request["type"]),                        SendTo = HttpContext.Request["to"],                        SendName = HttpContext.Request["from"]                    };                    if (m.SendType == 1)                    {                        m.SendTo = "All";                    }                    msgs.Store(m);//保存到Redis                    msgs.ExpireAt(m.Id, DateTime.Now.AddSeconds(60 * 1000));//redis记录的过期                    AsyncManager.Parameters["ret"] = new//构造返回对象格式                    {                        code = 200,                        ret = "Send OK!",                        what = ""                    };                    AsyncManager.OutstandingOperations.Decrement();//触发SendMessageCompleted的执行                }            }            catch (Exception ex)            {//错误处理                AsyncManager.Parameters["ret"] = new                {                    code = 500,                    ret = "",                    what = "Send error:"+ex.Message                };                AsyncManager.OutstandingOperations.Decrement();            }            mutex.ReleaseMutex();        }        public ActionResult SendMessageCompleted(object ret)        {//返回JSON对象            return Json(ret, JsonRequestBehavior.AllowGet);        }        public void GetMessageAsync()        {            mutex.WaitOne();            try            {                DateTime lastTime = Convert.ToDateTime(HttpContext.Request["time"]);                string user = HttpContext.Request["sendName"];                using (var msgs = redisClient.GetTypedClient<Message>())                {                    var msgFromRedis = msgs.GetAll().Where<Message>(                        msg => msg.SendTime > lastTime && (msg.SendTo == user|| msg.SendType == 1)                            && msg.SendName != user                        );//从Redis取数据,并设置查询条件                    var list = msgFromRedis.ToList<Message>();//查询结果                    IDictionary<string, object> ret = new Dictionary<string, object>();                    ret.Add("code", 200);//成功码                    ret.Add("ret", list);//返回结果                    ret.Add("what", "");                    AsyncManager.Parameters["ret"] = ret;//返回对象格式                    AsyncManager.OutstandingOperations.Decrement();//触发GetMessageCompleted的执行                }            }            catch (Exception ex)            {//错误处理                IDictionary<string, object> ret = new Dictionary<string, object>();                ret.Add("code", 500);//失败码                ret.Add("ret", "");                ret.Add("what", ex.Message);//错误内容                AsyncManager.Parameters["ret"] = ret;                AsyncManager.OutstandingOperations.Decrement();            }            mutex.ReleaseMutex();        }        public ActionResult GetMessageCompleted(IDictionary<string, object> ret)        {//返回JSON对象            return Json(ret, JsonRequestBehavior.AllowGet);        }    }}

3. 在《Global.asax.cs》文件中注册Routes方法改为:

        public static void RegisterRoutes(RouteCollection routes)        {            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");            routes.MapRoute(                "Default", // 路由名称                "{controller}/{action}/{id}", // 带有参数的 URL                new { controller = "Message", action = "Index", id = UrlParameter.Optional } // 参数默认值            );        }
4. 为Message控制器创建视图:《/Views/Message/Index.aspx》
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %><asp:Content ID="Content3" ContentPlaceHolderID="HeaderContent" runat="server">    <script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script>    <script src="../../Scripts/Message.js" type="text/javascript"></script>    <style type="text/css">        #logs        {            width: 360px;            height: 200px;        }    </style></asp:Content><asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">Index</asp:Content><asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">    <h2>Index</h2>    <textarea id="logs">    waiting...    </textarea>        <div id="sendBox">        <br />        昵称:<input type="text" id="sendName" name="sendName" value="" />        发送给:<input type="radio" id="sendType1" name="sendType" checked="checked" value="1" />所有人        发送给:<input type="radio" id="sendType2" name="sendType" value="0" /><input type="text" id="sendTo" name="sendTo" value="" />        内容:<input type="text" id="message" name="message" value="" />        <br />        <input type="submit" id="send" value="发送" onclick="sendMsg()"/>    </div></asp:Content>
5. 《Message.js》的内容:

//var i = 0;var lastTime = new Date();//首次打开网页时会以此时间开始取消息$(document).ready(function () {    $.ajaxSetup({ cache: false });    setInterval('long_polling(false)',5000);//每隔5秒取一次消息});//接收function long_polling(s) {    if (s) i++;    var sendname = $('#sendName').val();    var sendtype = $('#sendType1').attr("checked") ? 1 : 0;    var sendto = $('#sendTo').val();    var msg = $('#message').val();    var t = DateToString(lastTime);    $.ajax({        url: '/Message/GetMessage',        data: { 'sendName': sendname, 'time': t },        dataType: 'json',        error: function () { long_polling(false); },        success: function (data) {            if (data.code == 200) {                var d;                for (var item in data.ret) {                    if (data.ret[item].Msg) {                        d = ConvertJSONDateToJSDateObject(data.ret[item].SendTime);                        $('#logs').val(data.ret[item].SendName + "[" + DateToString(d) + "]对[" + (data.ret[item].SendType == 1 ? '所有人' : data.ret[item].SendTo) + "]说: " + data.ret[item].Msg + "\n" + $("#logs").val());                        lastTime = d;//更新最后一个消息的时间                    }                }            } else {                $("#logs").val('error:' + data.what + '\n' + $("#logs").val());            }        }    });}//发送function sendMsg() {    var sendname = $('#sendName').val();    var sendtype = $('#sendType1').attr("checked") ? 1 : 0;    var sendto = $('#sendTo').val();    var msg = $('#message').val();    var d = new Date();    var t = DateToString(d);    $.ajax({        url: '/Message/SendMessage',        data: { 'from': sendname, 'type': sendtype, 'to': sendto, 'msg': msg, 'time': t },        dataType: 'json',        success: function (data) {            if (data.code == 200) {                $("#logs").val(data.ret + '\n' + $("#logs").val());            }            else {                $("#logs").val(data.what + '\n' + $("#logs").val());            }        }    });}//时间转换function ConvertJSONDateToJSDateObject(JSONDateString) {    var date = new Date(parseInt(JSONDateString.replace("/Date(", "").replace(")/", ""), 10));    return date;}function DateToString(d) {    var t = d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() + ' ' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds();    return t;}

ServiceStack.Redis的资料,实在是太少了,这篇文章算是研究Redis与C#应用的一个实例吧!

改成了长轮询方式,js也加了连接超时保护,下载地址:

http://download.csdn.net/detail/cjy37/4004949

原创粉丝点击