C# 使用SignalR實現訊息通知
背景: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搭配進行定時排程傳送訊息
有興趣的朋友可以去看下如何使用Quartz來進行定時排程。
後面我也會更新一篇關於如何使用Quartz進行定時排程Job的文章。
相關文章
- 使用ABP SignalR重構訊息服務(一)SignalR
- 使用ABP SignalR重構訊息服務(二)SignalR
- 使用開源ntfy訊息推送服務釋出通知實現全平臺接收通知
- 【SignalR全套系列】之在.Net Core 中實現SignalR實時通訊SignalR
- jenkins2.235.5釘釘外掛實現訊息通知Jenkins
- 訊息通知 使用 [ Web-msg-sender]Web
- Laravel——訊息通知Laravel
- Laravel 訊息通知Laravel
- 使用 NSProxy 實現訊息轉發
- Django搭建個人部落格:用django-notifications實現訊息通知Django
- 使用Spring Boot實現訊息佇列Spring Boot佇列
- 【最佳實踐】微信小程式客服訊息實時通知如何快速低成本實現?微信小程式
- C#實現聊天訊息渲染、圖文混排(支援Windows、Linux)C#WindowsLinux
- 訊息通知系統記錄
- 鴻蒙傳送訊息通知鴻蒙
- redis學習(七) 訊息通知Redis
- Redis 使用 List 實現訊息佇列能保證訊息可靠麼?Redis佇列
- 使用者介面通知訊息的七個特徵 - modernanalyst特徵NaN
- 使用 Kotlin+RocketMQ 實現延時訊息KotlinMQ
- ASP.NET Core+Vue3 實現SignalR通訊ASP.NETVueSignalR
- js炫酷訊息通知外掛JS
- CommunityToolkit.Mvvm8.1 訊息通知(4)UnityMVVM
- 什麼是push通知欄訊息?
- 訊息通知(Notification)/使用者觸達系統設計
- 使用Mac通知中心,生活訊息一眼看盡!Mac
- workerman 實現訊息推送
- Go中使用Redis實現訊息佇列教程GoRedis佇列
- Redis使用ZSET實現訊息佇列使用總結一Redis佇列
- Redis使用ZSET實現訊息佇列使用總結二Redis佇列
- [C#] 使用 NAudio 實現音訊視覺化C#音訊視覺化
- 訊息通知(Notification)系統最佳化
- Flutter websocket 實現訊息推送FlutterWeb
- Redis實現訊息佇列Redis佇列
- Laravel 訊息通知原始碼閱讀筆記Laravel原始碼筆記
- X-Admin&ABP框架開發-訊息通知框架
- 一文教你實戰構建訊息通知系統DjangoDjango
- 透過.NET Core+Vue3 實現SignalR即時通訊功能VueSignalR
- 如何優雅的實現訊息通訊?