Asp.net SignalR 实现服务端消息推送到Web端
参考博客https://www.cnblogs.com/wintersun/p/4148223.html
ASP .NET SignalR是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信. 今天我们来实现服务端消息推送到Web端, 首先回顾一下它抽象层次图是这样的:
实际上 Asp.net SignalR 2 实现 服务端消息推送到Web端, 更加简单. 为了获取更好的可伸缩性, 我们引入消息队列, 看如下基本流程图:
消息队列MQ监听, 在Web site 服务端一收到消息,马上通过Signalr 推送广播到客户端. 创建ASP.NET MVC WEB APP, 从NuGet 安装SignalR 2.12
Install-Package Microsoft.AspNet.SignalR
具体实现代码,是这样的,我们增加一个空的Hub:
public class FeedHub : Hub{public void Init(){}}
是简单的消息模型, 标题与正文属性:
[Serializable]public class PushMessageModel{public int Id { get; set; }public string MSG_TITLE { get; set; }public string MSG_CONTENT { get; set; }}
服务端推送具体类,记录日志, 创建消息队列实例,监听, 等待收取消息. 这里我们使用的是AcitveMQ的.net客户端. ActiveMQListenAdapter是一个封装过的对象.
public class MQHubsConfig{private static ILogger log = new Logger("MQHubsConfig");/// <summary>/// Registers the mq listen and hubs./// </summary>public static void RegisterMQListenAndHubs(){var activemq = 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>();}}
上面有一句关键代码GlobalHost.ConnectionManager.GetHubContext<FeedHub>().Clients.All.receive(m); 这里使用了GetHubContext方法后,直接来广播消息.
需要在MVCApplication下加载:
public class MvcApplication : System.Web.HttpApplication{protected void Application_Start(){AreaRegistration.RegisterAllAreas();FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);MQHubsConfig.RegisterMQListenAndHubs();}}
同时需要增加一个Starup.cs, 用于Owin
[assembly: OwinStartup(typeof(RealTimeApp.Startup))]
namespace RealTimeApp
{public class Startup{public void Configuration(IAppBuilder app){// Any connection or hub wire up and configuration should go hereapp.MapSignalR();}}
}
接下来是客户端App.js:
function App() {var init = function () {Feed();$.connection.hub.logging = true;$.connection.hub.start().done(function() {console.log("Connected!");$(document).trigger("Connected");}).fail(function() { console.log("Could not Connect!"); });};init();
};
Feed.js 具体与SignalR.js通信, 创建名为receive的function, 与服务端对应
function Feed() {var chat = undefined;var init = function () {// Reference the auto-generated proxy for the hub.chat = $.connection.feedHub;// Create a function that the hub can call back to display messages.chat.client.receive = function (item) {var selector = "ul.feed-list li[data-id=" + item.Id + "]";if (!($(selector).length > 0)) {$("ul.feed-list").prepend($(".feed-template").render(item));$("ul.feed-list li:gt(3)").remove();}$.messager.show({title: 'Tips',msg: item.MSG_CONTENT,showType: 'show' });};// Start the connection.$.connection.hub.start().done(function () {chat.server.init();});};init();
};
上面的javascript代码与服务端有通信, 具体看如下图:
在Index.cshtml, 我们需要引用SignalR客户端JS, 放置hubs, 这里我们使用了jsrender, easyui.js 来呈现推送的消息.
@model dynamic@section Scripts {
<link href="/Content/themes/default/window.css" rel="stylesheet" />
<link href="~/Content/themes/default/progressbar.css" rel="stylesheet" />
<link href="~/Content/themes/default/linkbutton.css" rel="stylesheet" />
<script src="~/Scripts/jquery.signalR-2.1.2.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="~/signalr/hubs"></script><script src="~/Scripts/jsrender.js"></script>
<script src="~/Scripts/jquery.easyui.min-1.4.1.js"></script>@Scripts.Render("~/Scripts/project.js")<script type="text/javascript">$(document).ready(function () {var app = new App();});</script>
}<div class="row-fluid"><div class="span8"><div class="widget"><div class="widget-header"><h2>Feed</h2></div><div class="widget-content"><ul class="span12 feed-list"></ul></div></div></div>
</div><script class="chat-template" type="text/x-jquery-tmpl"><li><p>{{>Message}}</p></li>
</script><script class="feed-template" type="text/x-jquery-tmpl"><li data-id="{{>Id}}"><div class="row-fluid"><div class="span8"><h3>{{>MSG_CONTENT}}</h3></div></div></li>
</script>
上代码服务端引用js的Script.Render, 需要在BundleConfig.cs中加入以下代码:
bundles.Add(new ScriptBundle("~/Scripts/project.js").IncludeDirectory("~/Scripts/Project", "*.js", false));
同时我们构建一个WebAPI来发送需要推送的消息, 片断代码:
/// <summary>/// SendMessage/// </summary>/// <param name="messagemodel">The messagemodel.</param>/// <returns></returns>[HttpPost]public IHttpActionResult SendMessage(PushMessageModel messagemodel){return SendToServer(messagemodel);}/// <summary>/// Sends to server./// </summary>/// <param name="messagemodel">The messagemodel.</param>/// <returns></returns>private IHttpActionResult SendToServer(PushMessageModel messagemodel){if (ModelState.IsValid){if (messageRepository.SendMessage(messagemodel)){log.Debug("发送成功!");return Ok();}else{log.ErrorFormat("发送失败!{0}", messagemodel);return Content(HttpStatusCode.ExpectationFailed, new Exception("send message error"));}}else{log.ErrorFormat("参数验证失败!{0}", messagemodel);return Content(HttpStatusCode.BadRequest, ModelState);}}
发送消息到ActiveMQ的关键代码:
public class MessageRepository:IMessageRepository{private static ILogger log = new Logger("MessageRepository");/// <summary>/// 发送消息/// </summary>/// <param name="messagemodel"></param>/// <returns></returns>public bool SendMessage(PushMessageModel messagemodel){var activemq = new ActiveMQAdapter<PushMessageModel>(MQConfig.MQIpAddress, MQConfig.QueueDestination);return activemq.SendMessage<PushMessageModel>(messagemodel)>0;}}
如果您需要运行DEMO程序,需要构建基于ActiveMQ的消息队列, 运行效果是这样的, 我们在一个静态html中, 发送一个ajax到webapi服务端, 发送后
另一个website网站收到后, 列表更新, 并在右下角弹出框
IE的控制台输出:
HTML1300: Navigation occurred.
File: Index
[11:05:25 GMT+0800 (China Standard Time)] SignalR: Client subscribed to hub 'feedhub'.
[11:05:25 GMT+0800 (China Standard Time)] SignalR: Negotiating with '/signalr/negotiate?clientProtocol=1.4&connectionData=%5B%7B%22name%22%3A%22feedhub%22%7D%5D'.
[11:05:25 GMT+0800 (China Standard Time)] SignalR: This browser doesn't support SSE.
[11:05:25 GMT+0800 (China Standard Time)] SignalR: Binding to iframe's load event.
[11:05:25 GMT+0800 (China Standard Time)] SignalR: Iframe transport started.
[11:05:25 GMT+0800 (China Standard Time)] SignalR: foreverFrame transport selected. Initiating start request.
[11:05:25 GMT+0800 (China Standard Time)] SignalR: The start request succeeded. Transitioning to the connected state.
[11:05:25 GMT+0800 (China Standard Time)] SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332 and a connection lost timeout of 20000.
[11:05:25 GMT+0800 (China Standard Time)] SignalR: Invoking feedhub.Init
Connected!
[11:05:25 GMT+0800 (China Standard Time)] SignalR: Invoked feedhub.Init
[11:07:12 GMT+0800 (China Standard Time)] SignalR: Triggering client hub event 'receive' on hub 'FeedHub'.
[11:07:18 GMT+0800 (China Standard Time)] SignalR: Triggering client hub event 'receive' on hub 'FeedHub'.
[11:07:32 GMT+0800 (China Standard Time)] SignalR: Triggering client hub event 'receive' on hub 'FeedHub'.
[11:07:51 GMT+0800 (China Standard Time)] SignalR: Triggering client hub event 'receive' on hub 'FeedHub'.
[11:09:25 GMT+0800 (China Standard Time)] SignalR: Triggering client hub event 'receive' on hub 'FeedHub'.
上面粗体是 最后我们发的第5条信息控制台的输出.
好了,到这儿, 由于篇幅有限, 示例代码没有全部展示, 可以在这儿下载, 需要安装ActiveMQ
Asp.net SignalR 实现服务端消息推送到Web端相关推荐
- 手机消息推送之web端开发
最近的项目APP端需要添加消息推送任务.于是果断选择了极光消息推送.最最重要的原因就是开源免费. 极光开发者服务官网:https://www.jiguang.cn/
- pushlet实现单机-集群服务端消息推送
一.什么是pushlet? 1.pushlet推送是一种将java后台数据推送到web页面的框架技术,实现了comet. 2.comet是一个用于描述客户端和服务器之间交互的术语,即使用长期保持的ht ...
- web端消息推送的方式介绍
1.goeasy 官方地址:http://www.goeasy.io/ 集成简单,自己可以在官网上去看官方文档,12个月免费!值得一试. 2.dwr推送:官方地址http://directwebre ...
- Android端消息推送总结:实现原理、心跳保活、遇到的问题等
前言 最近研究Android推送的实现, 研究了两天一夜, 有了一点收获, 写下来既为了分享, 也为了吐槽. 需要说明的是有些东西偏底层硬件和通信行业, 我对这些一窍不通, 只能说说自己的理解. 为什 ...
- 即时通讯开发如何构建一套移动端消息推送系统
消息推送作为移动端 APP 运营中的一项关键技术,已经被越来越广泛的运用. 本文追溯了推送技术的发展历史,剖析了其核心原理,并对推送服务的关键技术进行深入剖析,围绕消息推送时产生的服务不稳定性,消息丢 ...
- APNS提供了两项基本的服务:消息推送和反馈服务
推送通知,也被叫做远程通知,是在iOS 3.0以后被引入的功能.是当程序没有启动或不在前台运行时,告诉用户有新消息的一种途径,是从外部服务器发送到应用程序上的.一般说来,当要显示消息或下载数据的时候, ...
- Hbuilder+Mui+个推实现移动端消息推送
注册个推账号 http://www.getui.com//cn/index.html在个推官网注册个推账号 登记应用 获取webapp的appid,如上图 保存后如下图: App端改造 移动端登陆后, ...
- SSE 服务端消息推送
SSE(Server-sent events) SSE 它是基于 HTTP 协议的,一般意义上的 HTTP 协议是无法做到服务端主动向客户端推送消息的.有一种变通方法,就是服务器向客户端声明,发送的是 ...
- SignalR 中丰富多彩的消息推送方式
在上一篇 SignalR 文章中,演示了如何通过 SignalR 实现了简单的聊天室功能:本着简洁就是美的原则,这一篇我们也来聊聊在 SignalR 中的用户和组的概念,理解这些基础知识有助于更好的开 ...
最新文章
- 长知识啦!字符也可以作为下标!_只愿与一人十指紧扣_新浪博客
- golang 切片排序
- 用神经网络模拟分子:钾的卤化物
- 随机重命名MP3文件
- Java学习笔记四:static关键字
- 教你移除IE 7.0浏览器的默认搜索框
- 苹果全新指纹识别专利过审 Touch ID或将重回iPhone
- Requests API
- 数据结构 队列Queue
- Excel数据转化为sql脚本
- linux勒索病毒如何恢复数据,勒索病毒和相应的解密工具
- Matlab求矩阵均值
- my games / BF3 / GTA5 / NFS18 / sanguowushuang6 / RA2 / KOF97 / FIFA
- BP反向传播算法推导
- 超实用的 Python 技巧,异步操作数据库!
- Cannot run code from this file in conjunction with non encoded files
- 阿里新推出“阿里云网盘”App,有机会干掉“百度网盘”吗?
- LOOP AT SCREEN ABAP
- 机器学习————神经网络
- 不是技术牛人,如何拿到国内巨头Offer
热门文章
- c# 第六课 linq
- 前端性能优化最佳实践(转)
- python显示行数_jupyter notebook实现显示行号
- java程序实验总结_Java Socket 编程实验总结
- 上周五 oracle,Oracle 获取上周一到周末日期的查询sql语句
- php 变更 obj,php怎么将object转为string
- win10 下载 linux系统安装教程,Win10安装Linux子系统图文教程
- id3决策树 鸢尾花 python_决策树算法——集成学的基础!
- opencv中的CommandLineParser类用法
- python面试总结 博客园_python面试题总结