前言:SignalR是基于.NET平台web应用的实时消息通讯框架,有人称之为.NET平台的.NodeJS;可用于Web页面聊天,消息推送等功能实现。本文摘取部分代码,利用.NET平台的Parallel功能实现通知消息的并行推送和批量存储。
1. 接收通知消息的Api接口:
MVC 控制器代码:
- [HttpPost]
- [AllowAnonymous]
- public void Notify(Message message)
- {
- var msgModel = new MessageModel();
- msgModel.Notify(message);
- }
-
- [HttpPost]
- [AllowAnonymous]
- public void Notify(List<Message> msgList)
- {
- var msgModel = new MessageModel();
- msgModel.BatchNotify(msgList);
- }
2. 通知消息的并行推送:
2.1 批量推送接口
首先调用到Task.Factory.StartNew()方法创建新任务,用BulkCopy()方法将数据批量插入到数据库;然后并行推送消息,因为消息接收人有多个,根据消息接收人的消息实体对象列表,Parallel.ForEach()对每条消息并行推送到Web用户的前端。
- /// <summary>
- /// 通知单条消息
- /// </summary>
- /// <param name="msg"></param>
- public void Notify(Message msg)
- {
- List<Message> msgList = new List<Message>();
- msgList.Add(msg);
- BatchNotify(msgList);
- }
-
- /// <summary>
- /// 多条消息列表推送
- /// </summary>
- /// <param name="msgList"></param>
- public void BatchNotify(List<Message> msgList)
- {
- //批量插入消息
- var msgService = new MessageService();
- Task.Factory.StartNew(() =>
- {
- msgService.BulkInsert(msgList);
- });
-
- IList<string> onlineConnectionIds = new List<string>();
- var hub = GlobalHost.ConnectionManager.GetHubContext<ClientPushHub>();
- var onlineUsers = ChatHub.GetOnlineUsersOnHub();
-
- //发送消息
- Parallel.ForEach<Message>(msgList, (msg) =>
- {
- PushMessage(msg, onlineUsers, hub);
- });
- }
2.2 调用SignalR 接口给在线用户发送通知消息
每条消息有多个接收人,每个接收人在前端的Connection连接存储在ConnectionIds集合中,遍历进行推送。
- /// <summary>
- /// 单条消息推送服务
- /// </summary>
- /// <param name="message">消息数据</param>
- private void PushMessage(Message msg, List<User> onlineUsers, IHubContext hub)
- {
- User user = null;
- List<RecieverEntity> recievers = msg.Recievers;
- foreach (var reciever in recievers)
- {
- user = onlineUsers.SingleOrDefault(a => a.Name == reciever.Reciever);
- if (user != null)
- {
- foreach (var connId in user.ConnectionIds)
- {
- hub.Clients.Client(connId).onPushingMessage(new
- {
- sender = msg.Sender,
- msgTitle = msg.MsgTitle,
- msgContent = msg.MsgContent,
- billUrl = msg.BillUrl,
- iframeTxt = msg.IframeTxt,
- iframeCode = msg.IframeCode,
- sendTime = DateTime.Now.ToString(),
- sendType = "notification"
- });
- }
- }
- }
- }
2.3 客户端接收通知消息
- //接收系统服务通知消息
- clientPushHub.client.onPushingMessage = function (message) {
- popNewMsgHintWindow(message);
- }
3. 批量消息的批量存储
3.1 批量插入
- /// <summary>
- /// 批量插入
- /// </summary>
- /// <param name="msgList"></param>
- public void BulkInsert(List<Message> msgList)
- {
- var msgTable = MsgBatchUtility.GetTableSchema();
- foreach (var msg in msgList)
- {
- Insert(msgTable, msg);
- }
- MsgBatchUtility.BulkCopy(msgTable);
- }
3.2 获取消息表结构
- /// <summary>
- /// 获取数据表Schema
- /// </summary>
- /// <returns></returns>
- public static DataTable GetTableSchema()
- {
- DataTable dt = new DataTable();
- dt.Columns.AddRange(new DataColumn[]{
- new DataColumn("MsgID", typeof(int)),
- new DataColumn("MsgType", typeof(byte)),
- new DataColumn("MsgTitle", typeof(string)),
- new DataColumn("MsgContent", typeof(string)),
- new DataColumn("Status", typeof(byte)),
- new DataColumn("SenderID", typeof(string)),
- new DataColumn("Sender", typeof(string)),
- new DataColumn("SendTime", typeof(DateTime)),
- new DataColumn("RecieverID", typeof(string)),
- new DataColumn("Reciever", typeof(string)),
- new DataColumn("RecievedTime", typeof(DateTime)),
- new DataColumn("AppName", typeof(string)),
- new DataColumn("AppInstanceID", typeof(string)),
- });
- return dt;
- }
3.3 数据库批量拷贝方法BulkCopy()
- /// <summary>
- /// 批量插入方法
- /// </summary>
- /// <param name="dt"></param>
- public static void BulkCopy(DataTable dt)
- {
- SqlConnection sqlConn = new SqlConnection(connectionString);
- SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConn);
- bulkCopy.DestinationTableName = "dbo.im_message";
- bulkCopy.BatchSize = dt.Rows.Count;
- try
- {
- sqlConn.Open();
- if (dt != null && dt.Rows.Count != 0)
- bulkCopy.WriteToServer(dt);
- }
- catch (Exception)
- {
- throw;
- }
- finally
- {
- sqlConn.Close();
- if (bulkCopy != null)
- bulkCopy.Close();
- }
- }
总结:
本文暂时没有对SignalR的用法和在线用户列表维护做出代码示例,会在后期文章中单独列出,SiganlR功能在做WebQQ聊天功能,网站页面聊天,聊天室功能时非常有用,有兴趣的开发人员可以以此为框架,搭建自己的实时通讯的工具,至于性能方法,SignalR评价是非常不错的,完全可以做企业级的分布式实时应用,有兴趣的读者可以访问官方站点了解。
百度搜索“就爱阅读”,专业资料,生活学习,尽在就爱阅读网92to.com,您的在线图书馆!