使用ASP.NET MVC 4 Async Action+jQuery实现消息通知机制的实现代码
这两天在使用asp.net mvc 4开发comet消息通知机制,在后端使用异步线程对消息进行订阅,客户端通过ajax长连接请求mvc中的action,如:http://localhost/event/imageset,即表示获取imageset对象的变更消息(新增,更新和删除消息)。
1.事件消息的类ievententity<tentity>类的定义
public interface ientityevent<tentity>
{
//变更的实体类对象
tentity[] entities
{
get;
}
//操作类型
entityeventtype type
{
get;
}
}
public enum entityeventtype : int
{
create = 0,
update = 1,
removed = 2
}
2.entityeventcontroller类
[sessionstate(sessionstatebehavior.readonly)]
public class entityeventcontroller : controller
{
//异步获取对imageset对象操作的变更事件action,millsecondstimeout为超时时间。
public async task<actionresult> imageset(int millisecondstimeout = 10000)
{
return await this.eventasync<imagesetdata>(millisecondstimeout);
}
private async task<actionresult> eventasync<tentity>(int millisecondstimeout)
{
ientityevent<tentity> entityevent = await entityeventsubcriber.instance.waitforentityevent<tentity>(millisecondstimeout);
return this.json(new
{
hasevent = null != entityevent,
entityevent = entityevent
}, jsonrequestbehavior.allowget);
}
}
(1)这里使用到了.net framework 4.5中使现异步asp.net mvc async action(可以参考:using asynchronous methods in asp.net mvc 4 技术文章)的技术,其中方法前的async关键字可以和task对象进行配合使用,表示该方法为异步方法,由编译器生成运行时所需的相关异步操作的逻辑代码,另外方法中必须使用到await语句来等待一个异步操作的结束,await和task<t>结合来返回task完成的result
(2) 如果controller层面应用或者filter中操作过session,那么为了避免长链接时不会导至同一session在其他调用中session block的情况,需要在controller头上加入[sessionstate(sessionstatebehavior.readonly)] 的attribute,来表示当前controller对session为只读操作,这样就其他操作就不会被阻塞了。
3.这里就不具体写entityeventsubscriber消息订阅器的代码了,以后将在“消息订阅与发布”的文章中详细描述。
4.jquery ajax客户端代码
$(document).ready(function () {
var $hoverlist = $("#imagesets").hoverlist({title:"图片集列表", selectedindex: 1 });
var getevent = function(){
var getpattern = "/easyshirtbackend/imageset/0";
$.getjson("/easyshirtbackend/event/imageset/100000" , function(data){
if(data.hasevent){
//create
if(data.entityevent.type == 0){
$.each(data.entityevent.entities, function(i, entity){
//todo: 处理实体类新增
if(i == data.entityevent.entities.length - 1){
getevent();
}
});
return;
}
//update
if(data.entityevent.type == 1){
$.each(data.entityevent.entities, function(i, entity){
//todo: 处理实体类更新
if(i == data.entityevent.entities.length - 1){
getevent();
}
});
return;
}
//delete
if(data.entityevent.type == 2){
$.each(data.entityevent.entities, function(i, entity){
//todo: 处理实体类删除
if(i == data.entityevent.entities.length - 1){
getevent();
}
});
}
}else{
$("#imagesets").hoverlist("add", data);
getevent();
}
});
};
getevent();
});
代码中主要需要控制住在一次获得消息(无论是有消息还是无消息),都需要在恰当的时机现一次的调用getevent()方法来进行消息获取的循环。
上一篇: Android ListView弹性效果的实现方法
下一篇: 智能手表开发API接口
推荐阅读