设为首页 收藏本站
查看: 1573|回复: 0

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

[复制链接]

尚未签到

发表于 2015-11-12 14:17:20 | 显示全部楼层 |阅读模式
  首先是安装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[&quot;msg&quot;],
SendTime = Convert.ToDateTime(HttpContext.Request[&quot;time&quot;]),
SendType = Convert.ToInt32(HttpContext.Request[&quot;type&quot;]),
SendTo = HttpContext.Request[&quot;to&quot;],
SendName = HttpContext.Request[&quot;from&quot;]
};
if (m.SendType == 1)
{
m.SendTo = &quot;All&quot;;
}
msgs.Store(m);//保存到Redis
msgs.ExpireAt(m.Id, DateTime.Now.AddSeconds(60 * 1000));//redis记录的过期
AsyncManager.Parameters[&quot;ret&quot;] = new//构造返回对象格式
{
code = 200,
ret = &quot;Send OK!&quot;,
what = &quot;&quot;
};
AsyncManager.OutstandingOperations.Decrement();//触发SendMessageCompleted的执行
}
}
catch (Exception ex)
{//错误处理
AsyncManager.Parameters[&quot;ret&quot;] = new
{
code = 500,
ret = &quot;&quot;,
what = &quot;Send error:&quot;+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[&quot;time&quot;]);
string user = HttpContext.Request[&quot;sendName&quot;];
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(&quot;code&quot;, 200);//成功码
ret.Add(&quot;ret&quot;, list);//返回结果
ret.Add(&quot;what&quot;, &quot;&quot;);
AsyncManager.Parameters[&quot;ret&quot;] = ret;//返回对象格式
AsyncManager.OutstandingOperations.Decrement();//触发GetMessageCompleted的执行
}
}
catch (Exception ex)
{//错误处理
IDictionary<string, object> ret = new Dictionary<string, object>();
ret.Add(&quot;code&quot;, 500);//失败码
ret.Add(&quot;ret&quot;, &quot;&quot;);
ret.Add(&quot;what&quot;, ex.Message);//错误内容
AsyncManager.Parameters[&quot;ret&quot;] = 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(&quot;{resource}.axd/{*pathInfo}&quot;);
routes.MapRoute(
&quot;Default&quot;, // 路由名称
&quot;{controller}/{action}/{id}&quot;, // 带有参数的 URL
new { controller = &quot;Message&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional } // 参数默认值
);
}4. 为Message控制器创建视图:《/Views/Message/Index.aspx》

<%@ Page Title=&quot;&quot; Language=&quot;C#&quot; MasterPageFile=&quot;~/Views/Shared/Site.Master&quot; Inherits=&quot;System.Web.Mvc.ViewPage<dynamic>&quot; %>

<asp:Content ID=&quot;Content3&quot; ContentPlaceHolderID=&quot;HeaderContent&quot; runat=&quot;server&quot;>
<script src=&quot;../../Scripts/jquery-1.4.1.js&quot; type=&quot;text/javascript&quot;></script>
<script src=&quot;../../Scripts/Message.js&quot; type=&quot;text/javascript&quot;></script>
<style type=&quot;text/css&quot;>
#logs
{
width: 360px;
height: 200px;
}
</style>
</asp:Content>

<asp:Content ID=&quot;Content1&quot; ContentPlaceHolderID=&quot;TitleContent&quot; runat=&quot;server&quot;>
Index
</asp:Content>
<asp:Content ID=&quot;Content2&quot; ContentPlaceHolderID=&quot;MainContent&quot; runat=&quot;server&quot;>
<h2>Index</h2>
<textarea id=&quot;logs&quot;>
waiting...
</textarea>
<div id=&quot;sendBox&quot;>
<br />
昵称:<input type=&quot;text&quot; id=&quot;sendName&quot; name=&quot;sendName&quot; value=&quot;&quot; />
发送给:<input type=&quot;radio&quot; id=&quot;sendType1&quot; name=&quot;sendType&quot; checked=&quot;checked&quot; value=&quot;1&quot; />所有人
发送给:<input type=&quot;radio&quot; id=&quot;sendType2&quot; name=&quot;sendType&quot; value=&quot;0&quot; /><input type=&quot;text&quot; id=&quot;sendTo&quot; name=&quot;sendTo&quot; value=&quot;&quot; />
内容:<input type=&quot;text&quot; id=&quot;message&quot; name=&quot;message&quot; value=&quot;&quot; />
<br />
<input type=&quot;submit&quot; id=&quot;send&quot; value=&quot;发送&quot; onclick=&quot;sendMsg()&quot;/>
</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(&quot;checked&quot;) ? 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 + &quot;[&quot; + DateToString(d) + &quot;]对[&quot; + (data.ret[item].SendType == 1 ? '所有人' : data.ret[item].SendTo) + &quot;]说: &quot; + data.ret[item].Msg + &quot;\n&quot; + $(&quot;#logs&quot;).val());
lastTime = d;//更新最后一个消息的时间
}
}
} else {
$(&quot;#logs&quot;).val('error:' + data.what + '\n' + $(&quot;#logs&quot;).val());
}
}
});
}
//发送
function sendMsg() {
var sendname = $('#sendName').val();
var sendtype = $('#sendType1').attr(&quot;checked&quot;) ? 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) {
$(&quot;#logs&quot;).val(data.ret + '\n' + $(&quot;#logs&quot;).val());
}
else {
$(&quot;#logs&quot;).val(data.what + '\n' + $(&quot;#logs&quot;).val());
}
}
});
}
//时间转换
function ConvertJSONDateToJSDateObject(JSONDateString) {
var date = new Date(parseInt(JSONDateString.replace(&quot;/Date(&quot;, &quot;&quot;).replace(&quot;)/&quot;, &quot;&quot;), 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.iyunv.com/detail/cjy37/4004949



版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-138387-1-1.html 上篇帖子: Redis数据持久化机制AOF原理分析之配置详解 下篇帖子: Python操作Redis之设置key的过期时间
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表