Asp.net SignalR 实现服务端消息推送到Web端
2016-08-23 16:50
806 查看
之前的文章介绍过Asp.netSignalR,ASP.NETSignalR是一个ASP.NET下的类库,可以在ASP.NET的Web项目中实现实时通信.今天我们来实现服务端消息推送到Web端,首先回顾一下它抽象层次图是这样的:
实际上Asp.netSignalR2实现服务端消息推送到Web端,更加简单.为了获取更好的可伸缩性,我们引入消息队列,看如下基本流程图:
消息队列MQ监听,在Website服务端一收到消息,马上通过Signalr推送广播到客户端.创建ASP.NETMVCWEBAPP,从NuGet安装SignalR2.12
Install-PackageMicrosoft.AspNet.SignalR
具体实现代码,是这样的,我们增加一个空的Hub:
[code]{
[/code]
是简单的消息模型,标题与正文属性:
[code]publicclassPushMessageModel
[/code]
实际上Asp.netSignalR2实现服务端消息推送到Web端,更加简单.为了获取更好的可伸缩性,我们引入消息队列,看如下基本流程图:
消息队列MQ监听,在Website服务端一收到消息,马上通过Signalr推送广播到客户端.创建ASP.NETMVCWEBAPP,从NuGet安装SignalR2.12
Install-PackageMicrosoft.AspNet.SignalR
具体实现代码,是这样的,我们增加一个空的Hub:
publicclassFeedHub:Hub
[code]{
publicvoidInit()
{
}
}
[/code]
是简单的消息模型,标题与正文属性:
[Serializable]
[code]publicclassPushMessageModel
{
publicintId{get;set;}
publicstringMSG_TITLE{get;set;}
publicstringMSG_CONTENT{get;set;}
}
[/code]
服务端推送具体类,记录日志,创建消息队列实例,监听,等待收取消息.这里我们使用的是AcitveMQ的.net客户端.ActiveMQListenAdapter是一个封装过的对象.
publicclassMQHubsConfig
[code]{
privatestaticILoggerlog=newLogger("MQHubsConfig");
///<summary>
///Registersthemqlistenandhubs.
///</summary>
publicstaticvoidRegisterMQListenAndHubs()
{
varactivemq=Megadotnet.MessageMQ.Adapter.ActiveMQListenAdapter<PushMessageModel>.Instance(MQConfig.MQIpAddress,MQConfig.QueueDestination);
activemq.MQListener+=m=>
{
log.InfoFormat("从MQ收到消息{0}",m.MSG_CONTENT);
GlobalHost.ConnectionManager.GetHubContext<FeedHub>().Clients.All.receive(m);
};
activemq.ReceviceListener<PushMessageModel>();
}
}
[/code]
上面有一句关键代码GlobalHost.ConnectionManager.GetHubContext<FeedHub>().Clients.All.receive(m);这里使用了GetHubContext方法后,直接来广播消息.
需要在MVCApplication下加载:
publicclassMvcApplication:System.Web.HttpApplication
[code]{
protectedvoidApplication_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
MQHubsConfig.RegisterMQListenAndHubs();
}
}
[/code]
同时需要增加一个Starup.cs,用于Owin
[assembly:OwinStartup(typeof(RealTimeApp.Startup))]
[code]namespaceRealTimeApp
{
publicclassStartup
{
publicvoidConfiguration(IAppBuilderapp)
{
//Anyconnectionorhubwireupandconfigurationshouldgohere
app.MapSignalR();
}
}
}
[/code]
接下来是客户端App.js:
functionApp(){
[code]varinit=function(){
Feed();
$.connection.hub.logging=true;
$.connection.hub.start()
.done(function(){
console.log("Connected!");
$(document).trigger("Connected");
})
.fail(function(){console.log("CouldnotConnect!");});
};
init();
};
[/code]
Feed.js具体与SignalR.js通信,创建名为receive的function,与服务端对应
functionFeed(){
[code]varchat=undefined;
varinit=function(){
//Referencetheauto-generatedproxyforthehub.
chat=$.connection.feedHub;
//Createafunctionthatthehubcancallbacktodisplaymessages.
chat.client.receive=function(item){
varselector="ul.feed-listli[data-id="+item.Id+"]";
if(!($(selector).length>0)){
$("ul.feed-list").prepend($(".feed-template").render(item));
$("ul.feed-listli:gt(3)").remove();
}
$.messager.show({
title:'Tips',
msg:item.MSG_CONTENT,
showType:'show'
});
};
//Starttheconnection.
$.connection.hub.start().done(function(){
chat.server.init();
});
};
init();
};
[/code]
上面的javascript代码与服务端有通信,具体看如下图:
在Index.cshtml,我们需要引用SignalR客户端JS,放置hubs,这里我们使用了jsrender,easyui.js来呈现推送的消息.
@modeldynamic
[code]
@sectionScripts{
<linkhref="/Content/themes/default/window.css"rel="stylesheet"/>
<linkhref="~/Content/themes/default/progressbar.css"rel="stylesheet"/>
<linkhref="~/Content/themes/default/linkbutton.css"rel="stylesheet"/>
<scriptsrc="~/Scripts/jquery.signalR-2.1.2.min.js"></script>
<!--ReferencetheautogeneratedSignalRhubscript.-->
<scriptsrc="~/signalr/hubs"></script>
<scriptsrc="~/Scripts/jsrender.js"></script>
<scriptsrc="~/Scripts/jquery.easyui.min-1.4.1.js"></script>
@Scripts.Render("~/Scripts/project.js")
<scripttype="text/javascript">
$(document).ready(function(){
varapp=newApp();
});
</script>
}
<divclass="row-fluid">
<divclass="span8">
<divclass="widget">
<divclass="widget-header">
<h2>Feed</h2>
</div>
<divclass="widget-content">
<ulclass="span12feed-list"></ul>
</div>
</div>
</div>
</div>
<scriptclass="chat-template"type="text/x-jquery-tmpl">
<li>
<p>{{>Message}}</p>
</li>
</script>
<scriptclass="feed-template"type="text/x-jquery-tmpl">
<lidata-id="{{>Id}}">
<divclass="row-fluid">
<divclass="span8">
<h3>{{>MSG_CONTENT}}</h3>
</div>
</div>
</li>
</script>
[/code]
上代码服务端引用js的Script.Render,需要在BundleConfig.cs中加入以下代码:
bundles.Add(newScriptBundle("~/Scripts/project.js")
.IncludeDirectory("~/Scripts/Project","*.js",false));
同时我们构建一个WebAPI来发送需要推送的消息,片断代码:
///<summary>
[code]///SendMessage
///</summary>
///<paramname="messagemodel">Themessagemodel.</param>
///<returns></returns>
[HttpPost]
publicIHttpActionResultSendMessage(PushMessageModelmessagemodel)
{
returnSendToServer(messagemodel);
}
///<summary>
///Sendstoserver.
///</summary>
///<paramname="messagemodel">Themessagemodel.</param>
///<returns></returns>
privateIHttpActionResultSendToServer(PushMessageModelmessagemodel)
{
if(ModelState.IsValid)
{
if(messageRepository.SendMessage(messagemodel))
{
log.Debug("发送成功!");
returnOk();
}
else
{
log.ErrorFormat("发送失败!{0}",messagemodel);
returnContent(HttpStatusCode.ExpectationFailed,newException("sendmessageerror"));
}
}
else
{
log.ErrorFormat("参数验证失败!{0}",messagemodel);
returnContent(HttpStatusCode.BadRequest,ModelState);
}
}
[/code]
发送消息到ActiveMQ的关键代码:
publicclassMessageRepository:IMessageRepository
[code]{
privatestaticILoggerlog=newLogger("MessageRepository");
///<summary>
///发送消息
///</summary>
///<paramname="messagemodel"></param>
///<returns></returns>
publicboolSendMessage(PushMessageModelmessagemodel)
{
varactivemq=newActiveMQAdapter<PushMessageModel>(MQConfig.MQIpAddress,MQConfig.QueueDestination);
returnactivemq.SendMessage<PushMessageModel>(messagemodel)>0;
}
}
[/code]
如果您需要运行DEMO程序,需要构建基于ActiveMQ的消息队列,运行效果是这样的,我们在一个静态html中,发送一个ajax到webapi服务端,发送后
另一个website网站收到后,列表更新,并在右下角弹出框
IE的控制台输出:
HTML1300:Navigationoccurred.
File:Index
[11:05:25GMT+0800(ChinaStandardTime)]SignalR:Clientsubscribedtohub'feedhub'.
[11:05:25GMT+0800(ChinaStandardTime)]SignalR:Negotiatingwith'/signalr/negotiate?clientProtocol=1.4&connectionData=%5B%7B%22name%22%3A%22feedhub%22%7D%5D'.
[11:05:25GMT+0800(ChinaStandardTime)]SignalR:Thisbrowserdoesn'tsupportSSE.
[11:05:25GMT+0800(ChinaStandardTime)]SignalR:Bindingtoiframe'sloadevent.
[11:05:25GMT+0800(ChinaStandardTime)]SignalR:Iframetransportstarted.
[11:05:25GMT+0800(ChinaStandardTime)]SignalR:foreverFrametransportselected.Initiatingstartrequest.
[11:05:25GMT+0800(ChinaStandardTime)]SignalR:Thestartrequestsucceeded.Transitioningtotheconnectedstate.
[11:05:25GMT+0800(ChinaStandardTime)]SignalR:Nowmonitoringkeepalivewithawarningtimeoutof13333.333333333332andaconnectionlosttimeoutof20000.
[11:05:25GMT+0800(ChinaStandardTime)]SignalR:Invokingfeedhub.Init
Connected!
[11:05:25GMT+0800(ChinaStandardTime)]SignalR:Invokedfeedhub.Init
[11:07:12GMT+0800(ChinaStandardTime)]SignalR:Triggeringclienthubevent'receive'onhub'FeedHub'.
[11:07:18GMT+0800(ChinaStandardTime)]SignalR:Triggeringclienthubevent'receive'onhub'FeedHub'.
[11:07:32GMT+0800(ChinaStandardTime)]SignalR:Triggeringclienthubevent'receive'onhub'FeedHub'.
[11:07:51GMT+0800(ChinaStandardTime)]SignalR:Triggeringclienthubevent'receive'onhub'FeedHub'.
[11:09:25GMT+0800(ChinaStandardTime)]SignalR:Triggeringclienthubevent'receive'onhub'FeedHub'.
上面粗体是最后我们发的第5条信息控制台的输出.
好了,到这儿,由于篇幅有限,示例代码没有全部展示,可以在这儿
相关文章推荐
- Asp.net SignalR 实现服务端消息推送到Web端
- Asp.net SignalR 实现服务端消息推送到Web端
- AngularJS+ASP.NET MVC+SignalR实现消息推送
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(九) 之 用 Redis 实现用户在线离线状态消息处理(一)
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十) 之 自定义系统消息和总结
- AngularJS+ASP.NET MVC+SignalR实现消息推送
- AngularJS+ASP.NET MVC+SignalR实现消息推送
- AngularJS+ASP.NET MVC+SignalR实现消息推送
- asp.net使用signalr实现集群集群下面的消息推送
- AngularJS+ASP.NET MVC+SignalR实现消息推送
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(五) 之 加好友,加群流程,消息管理和即时消息提示的实现
- AngularJS+ASP.NET MVC+SignalR实现消息推送
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(八) 之 用 Redis 实现用户在线离线状态消息处理
- AngularJS+ASP.NET MVC+SignalR实现消息推送
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十四)之漏掉的客服消息
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能
- SignalR SelfHost实时消息,集成到web中,实现服务器消息推送
- SignalR 实现web浏览器客户端与服务端的推送功能
- Asp.NET MVC 中使用 SignalR 实现推送功能