C# 使用SignalR实现消息通知

2023-11-19

背景:Web端需要能实时接收到消息推送,当客户有新消息来时,在客户端的右下角进行弹框提醒。

什么是signalR?

Asp.net SignalR是微软为实现实时通信的一个类库。一般情况下,signalR会使用JavaScript的长轮询(long polling)的方式来实现客户端和服务器通信,随着Html5中WebSockets出现,SignalR也支持WebSockets通信。另外SignalR开发的程序不仅仅限制于宿主在IIS中,也可以宿主在任何应用程序,包括控制台,客户端程序和Windows服务等,另外还支持Mono,这意味着它可以实现跨平台部署在Linux环境下。

signalR内部有两类对象:

Http持久连接(Persisten Connection)对象:用来解决长时间连接的功能。还可以由客户端主动向服务器要求数据,而服务器端不需要实现太多细节,只需要处理PersistentConnection 内所提供的五个事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。
Hub(集线器)对象:用来解决实时(realtime)信息交换的功能,服务端可以利用URL来注册一个或多个Hub,只要连接到这个Hub,就能与所有的客户端共享发送到服务器上的信息,同时服务端可以调用客户端的脚本。SignalR将整个信息的交换封装起来,客户端和服务器都是使用JSON来沟通的,在服务端声明的所有Hub信息,都会生成JavaScript输出到客户端,.NET则依赖Proxy来生成代理对象,而Proxy的内部则是将JSON转换成对象。

SignalR将整个信息的交换封装起来,客户端和服务器都是使用JSON来沟通的,在服务端声明的所有Hub信息,都会生成JavaScript输出到客户端,.NET则依赖Proxy来生成代理对象,而Proxy的内部则是将JSON转换成对象。

客户端和服务端的具体交互情况如下图所示:

 

基本流程如图:

 

其实说白点SignalR其实就是微软自己封装好的实现即时通讯的一个类库

如何使用:

Nuget引入 Microsoft.AspNet.SignalR 系列 2.4.1

 

添加完signalR你可以在 Scripts 文件夹下看到自动添加了两个js文件:

 

向项目中添加一个signalR集线器(V2)命名为ServerHub:

 

在刚刚新建的ServerHub.cs 中写入 以下代码:

//*********************************************************************************
//Description:自定义扩展一个消息通知类库模块>集线器
//Author:DennyHui
//Create Date: 2019年10月15日18:39:33
//*********************************************************************************
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
 
namespace Fisk.DataWithReportManage.AutoTask
{
    /// <summary>
    /// 消息通知集线器  2019年10月16日12:28:08  Dennyhui
    /// </summary>
    [HubName("serverhub")]
    public class ServerHub:Hub
    {
        /// <summary>
        /// 发送消息 2019年10月16日12:28:18  Dennyhui
        /// </summary>
        /// <param name="message"></param>
        public void SendMsg(string id,string title, string message,string poptype)
        {
            //调用所有客户端的sendMessage方法(sendMessage有2个参数)  
            //Clients.All.SendMessage("测试");
            //Clients.All.broadcastMessage("测试");
            //Clients.All.notify("测试");
            var hubContext = GlobalHost.ConnectionManager.GetHubContext<ServerHub>();//此处的“ServerHub”需要和当前的类名一直
            hubContext.Clients.All.sendMessage(id,title,message, poptype); //用户调用客户端的函数 
            //Clients.All.sendMessage(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "测试");
        }
        /// <summary>
        /// 实例化  2019年10月16日12:28:31  Dennhui
        /// </summary>
        public void Init() { }
    }
}

如果你的mvc项目是不进行身份验证的那种吧,必须得添加一个Startup 类.      如果没有这个类,请添加,不然的话项目运行不起来的,具体代码如下:

using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRQuickStart.Startup))]
 
namespace SignalRQuickStart
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888
            // 配置集线器
            app.MapSignalR();
        }
    }
}
在Control 里新建一个MessageAction方法,在Message视图里添加代码如下:

@{
    ViewBag.title = "SignaIR聊天窗口";
}
    <div class="container">
        <input type="text" id="message" />
        <input type="button" id="sendmessage" value="Send" />
        <input type="hidden" id="displayname" />
        <ul id="messageBox"></ul>
    </div>
@section scripts
{
   <script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script>
   <script src="~/signalr/hubs"></script>
    <script>
        $(function () {
            //引用自动生成的集线器代理
            var chat = $.connection.serverHub;
             //定义服务器调用的客户端sendMessage来显示新消息
            chat.client.sendMessage = function (name, message)
            {
                //向页面添加消息
                $("#messageBox").append('<li><strong style="color:green">'+htmlEncode(name)+'</strong>:'+htmlEncode(message)+'</li>');
            }
            //设置焦点到输入框
            $('#message').focus();
            //开始连接服务器
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
                    //调用服务器端集线器的Send方法
                    chat.server.sendMsg($('#message').val());
                    //清空输入框信息并获取焦点
                    $("#message").val('').focus();
                })
            })
        });
        //为显示的消息进行html编码
        function htmlEncode(value)
        {
            var encodeValue = $('<div/>').text(value).html();
            return encodeValue;
        }
    </script>
}

         //消息通知  2019年10月15日18:38:56  Dennyhui
        function  SignalRMessage () {
            //toastr.info("向页面添加消息  ", "新消息");
            var NowDateNoticeList = window.WebNotificationList;
            //引用自动生成的集线器代理  
            var chat = $.connection.serverhub;
            //定义服务器调用的客户端sendMessage来显示新消息  
            //此处的“sendMessage”需要和后台发送消息的方法名一致
            chat.client.sendMessage = function (id, title, message, poptype) {
                
                // do somethings
               
            }
            //集线器开始工作
            $.connection.hub.start().done(function () {
                chat.server.init();
            });

好了,一个signalR简单的入门的例子就ok了.

在任何一个web 页面中发送的消息所有的 页面都会接收到该消息。这种应用在IM系统非常广泛常见。

当然signalR并不局限于这种B/S模式的消息推送,在C/S 同样也能应用,目前我们公司xamarin android所用的就是这个signalR实现的PC之间、PC与移动端、移动端与移动端之间的交流,使用之后会发现的确挺方便的。

有人可能感觉很郁闷了,在视图中引入 这段js有什么作用?也并有写啊。

注意!,这是虚拟目录,也就是你在OWIN Startup中注册的地址

<script src="~/signalr/hubs"></script>
这个路径你在项目里面是找不到的!

其实在服务器端声明的所有Hub信息,最终都会生成JavaScript输出到客户端,其实谷歌浏览器中F12 ,在Sources你就可以看到写的源代码了:

 

来看一下在这种B/S 模式中 signalR是如何运行的吧。首先程序开始的时候,Web页面就已经与signalR的服务建立连接。

$.connection.hub.start() 意思就是有signalR服务建立连接

.done 函数表示连接成功后为发送的按钮绑定一个单击事件

发送消息的方法:chat.server.sendMsg($('#message').val())

在ServerHub重写一个 OnConnected 方法来监控客户端的连接情况,的确程序运行的时候web页面就已经开始建立连接了,在调试的时候可以在输入中看到 "客户端连接成功!

一个简单的如何使用signalR就是这么多,用法很广泛,当然还可以进行扩展。

可以使用Quartz这个组件和Signalr搭配进行定时调度发送消息


————————————————
版权声明:本文为CSDN博主「Denny辉」的原创文章
原文链接:https://blog.csdn.net/qq_23502409/article/details/102968078

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 使用SignalR实现消息通知 的相关文章

随机推荐

  • 5、DML语句(数据操纵语言-增删改查)

    文章目录 一 DML语句介绍 二 insert 增加 插入数据 1 基本语法 2 示例 三 delete 删除表中的某行或者某些行数据 1 基本语法 2 示例 四 update 更新 修改 1 基本语法 2 示例 五 select 查询 1
  • 软件和建筑的结构

    一般都倾向于将软件比作建筑 因为建筑的架构和软件框架类似 好的建筑需要好的框架 但是大家忽略了另外一个情况 一个建筑要能居住 不但要好的建 筑风格和框架 更需要有好的家居和内部装修 建筑居住的舒适度很大程度上由内部装修细节决定的 装修时家居
  • 程序员,职场上请远离这种人!

    对有些职场人来讲 甩锅就是一种生存手段 01 从大学打篮球说起 上大学的时候喜欢打篮球 然后我又特别喜欢抢篮板 经常是跳起来的时候没事 落下来的时候偶尔会踩到别人的脚上 于是左脚经常性崴脚 这是背景 我们班上有一个同学也喜欢打篮球 我俩水平
  • 多媒体透明屏,在户外广告领域中,有哪些应用展示?

    多媒体透明屏是一种新型的显示技术 它能够将图像和视频直接投射到透明的屏幕上 使得观众可以同时看到屏幕后面的实物 这种技术在广告 展览 商场等场合有着广泛的应用前景 多媒体透明屏的原理是利用透明显示技术 将图像和视频通过光学投射技术投射到透明
  • 【C语言初学】作业:计算在贷款第一个月、第二个月、第三个月后需要还款金额

    贷款金额 20000 00元 年贷款利率 6 0 每个月还款金额 386 66 第一个月剩余的需还款金额 19713 34元 第二个月剩余的需还款金额 19425 25元 第三个月剩余的需还款金额 19135 71元 提示 每个月剩余的贷款
  • 深入浅出 sideEffects

    前言 最近在给团队对 webpack 中的 sideEffects 字段用途进行微分享 于是乎 我最后就整理成一篇文章 希望帮助更多的人理解 sideEffects 的作用 sideEffects 是什么呢 我用一句话来概括就是 让 web
  • redis 安装配置

    原文链接 https www cpweb top 1266 一 介绍 Redis 是一个开源的 基于内存的数据结构存储系统 它可以用作数据库 缓存和消息中间件 它是一个键值 Key Value 存储数据库 为非关系型数据库 它支持多种类型的
  • 在el-table的功能,并且在单元格里面加入输入框

    在我们的前端拿到后端返回的数据的时候 需要在el table的功能 并且在单元格里面加入输入框 为了让输入框的输入时候不会影响到其他的输入框 可以使用 input来获取输入框内容的值
  • python 多个logger对象使用,输出到多个文件

    就不介绍logger基础配置了 如何创建多个logger对象 输出到多个文件 import logging from datetime import datetime def get logger name logger logging g
  • 解决BookxNotePro在linux下无法启动或GLIBC_2.29‘ not found的问题

    问题描述如题 命令行启动出现如下报错 usr local BookxNotePro BookxNotePro usr local BookxNotePro BookxNotePro lib x86 64 linux gnu libm so
  • JS声明二维数组常见办法

    JS声明二维数组常见办法 目录 文章目录 前言 new Array 和 fill fill 灵活插入 for 笨办法 Array from 前言 目前论坛常见的办法代码质量奇差 因此针对这个问题进行整理 new Array和fill con
  • 使用机器学习算法打造一个简单的“微博指数”

    欢迎大家前往腾讯云技术社区 获取更多腾讯海量技术实践干货哦 作者 林浩威 前言 随着人工智能的大热 越来越多的小伙伴们开始投身到机器学习的大潮中 作为其中的一员 我对此也是极有兴趣的 当然我更感兴趣的 是怎么利用这些有趣的算法 来实现脑海里
  • element样式无法修改

    在使用el form组件时 组件中的字体是黑色的 需要显示白色字体就加了个color fff 结果发现修改并没有什么效果 还是原来的黑色 打开F12发现属于 el form item label选择器下面的 我就在css下面修改了该选择器
  • 端口占用查询

    我们做WEB开发 本地调试时 有时出现 Caused by java net BindException Address already in use bind at sun nio ch Net bind0 Native Method a
  • 机械孔与盲孔

    过孔是什么 过孔 Via 电路板上的孔 连接不同层之间的线路 把电路板从平面结构变成立体结构 单层线路想不交叉太难了 双层或更多层线路 必须通过过孔来连接 通过孔壁上的铜 连通上下层的电路铜线 单层PCB 有些时候无法布线 必须通过过孔换层
  • Chisel手册之Types

    本文是Chisel手册第二篇Types Types 表示硬件设计的Chisel图包含原始节点和类型节点 Chisel类型系统与底层Scala类型系统分开维护 因此类型节点散布在原始节点之间 以允许Chisel检查并响应Chisel类型 Ch
  • 微信小程序 实现底部导航栏tabbar

    参考链接 1 微信小程序底部导航Tabbar https www cnblogs com huangjialin p 6278429 html 2 小程序自定义tabbar实现中间图标突出效果 附带wx hideTabBar不生效的bug解
  • Spring Boot 启动报错解决:No active profile set, falling back to default profiles: default

    在SpringBoot启动时 控制台打印出来的信息有这么一条 No active profile set falling back to default profiles default 如下图 这句话的意思是 没有指定项目的配置文件 使用
  • Skyfire: 一种用于Fuzzing的数据驱动的种子生成工具

    Skyfire Data Driven Seed Generation for Fuzzing 作者 杨鑫 清华大学 论文发表于 IEEE S P 2017 原文作者 Junjie Wang Bihuan Chen Lei Wei and
  • C# 使用SignalR实现消息通知

    背景 Web端需要能实时接收到消息推送 当客户有新消息来时 在客户端的右下角进行弹框提醒 什么是signalR Asp net SignalR是微软为实现实时通信的一个类库 一般情况下 signalR会使用JavaScript的长轮询 lo