RedisベースのASP.NETとjs(AJAX)のチャットプログラム[js長接続][ダミープッシュ]


まずRedisをインストールします.ここではnステップを省略します.
次に、ASPを新規作成します.NETのMVC 2のプロジェクト『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 + "
" + $("#logs").val()); lastTime = d;// } } } else { $("#logs").val('error:' + data.what + '
' + $("#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 + '
' + $("#logs").val()); } else { $("#logs").val(data.what + '
' + $("#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#の応用を研究する1つの例でしょう!
ロングポーリング方式に変更され、jsにも接続タイムアウト保護が追加され、ダウンロードアドレス:
http://download.csdn.net/detail/cjy37/4004949