背景
OA 管理システムでは、従業員が申請フォームを提出し、そのメッセージがタイムリーな承認のために関係者にリアルタイムで通知され、承認後に結果がユーザーにプッシュされます。
テクノロジーの選択
私が最初に発見したのは firebase だったので、とても興奮しながら推測を始めました。 Firebase の使い方は簡単です。js を引用し、公式 Web サイトのチュートリアルに従うだけで、すぐにプロジェクトに適用できます。翌日プロジェクトを開いたところ、プッシュ機能が動作していないことがわかりました。なぜでしょうか。結局、firebaseの公式サイトが開けないことが分かりました。 。 。 Firebase が Google に乗っ取られたら、中国からもブロックされる可能性はありますか?もしかしたらfirebase自体がハングアップしてしまい、もう使用できなくなってしまっているのかもしれません。 Push 機能を実装するには、Push データを Firebase サーバーに完全に保存する必要があるため、次のような問題が発生します:
1. Firebase への依存度が高すぎる
3.無料版は弱すぎます)
そこで、友人が SignalR というものを勧めてくれました。これは、他のサーバーに依存しない、ASP.NET 開発者向けのメッセージ プッシュ ライブラリです。
使い方
1. nuget で最新バージョンの SignalR を検索して追加します
2. ページ内の jquery.signalR-2.2.0.min.js ファイルを参照し、次に、signalr を自動的に生成するために使用されるスクリプトを追加します
3. 対応するユーザー情報を処理するための MsgHub.cs クラスとメッセージ プッシュ実装を追加します
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; namespace ZmeiOA.Services { [Authorize] [HubName("ZmHub")] public class MsgHub : Hub {/// <summary> /// 连接 /// </summary> /// <returns></returns> public override System.Threading.Tasks.Task OnConnected() { Groups.Add(Context.ConnectionId, Context.User.Identity.Name); return base.OnConnected(); } /// <summary> /// 重新连接 /// </summary> /// <returns></returns> public override System.Threading.Tasks.Task OnReconnected() { Groups.Add(Context.ConnectionId, Context.User.Identity.Name); return base.OnReconnected(); } /// <summary> /// 断开连接 /// </summary> /// <param name="stopCalled"></param> /// <returns></returns> public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled) { Groups.Remove(Context.ConnectionId, Context.User.Identity.Name); return base.OnDisconnected(stopCalled); } } }
説明: SignalR プッシュ メッセージはユーザー接続 (ConnectionId) に基づいており、SignalR はセッションごとに ConnectionId を自動的に生成します。ただし、私たちのプッシュはユーザー (権限システム) に基づいています。つまり、ログイン後にのみこのハブに登録できます。ここで使用するのは SignalR の Groups で、ログイン ユーザーの ConnectionId と対応する UserId を Groups に追加します。プッシュするときは、グループの名前を指定するだけで、SignalR が対応する ConnectionId を自動的に見つけて送信します。メッセージ (この方法は、各ユーザーの UserId がグループのキーとして追加されるため、最適ではない可能性があります。ユーザーの数が多い場合、グループも非常に大きくなりますが、より良い代替案はまだ見つかりません) 。
4. メッセージのプッシュには 2 つの形式があります: a. サーバーからの直接プッシュ。
違いは、サーバー側のプッシュはデータを永続化した後、関連するユーザーにメッセージを直接プッシュできることですが、クライアント側のプッシュはデータを永続化した後、クライアントは SignalR の JS メソッドを使用して、プッシュ関数。データを永続化した後、フロントに戻ってサーバーのプッシュ メソッドを呼び出すと、業務に応じて関係者に通知できるため、サーバーを使用してデータを直接プッシュします。
例:申請フォーム保存後すぐに承認者に通知
サービス内のHubのコンテキストを取得
/// <summary> /// 消息推送上下文 /// </summary> protected static IHubContext ZmHubContext = GlobalHost.ConnectionManager.GetHubContext<MsgHub>();
申請フォーム保存後、関係者にメッセージをプッシュ(注:動的メソッドbroadcastTodoはクライアントがメッセージ メソッドを受信する必要がある場合)
public static ApplyForm Save(FormView view) { //省略业务操作... //... //通知待办事项 ZmHubContext.Clients.Groups(app.AuditorIds.Split(',')).broadcastTodo(app.AuditorIds, new { type = "new", data = app }); return app; }
5. Angular モジュールを登録するときにハブを接続し、それを値としてモジュールに渡し、各コントローラーがこの接続を使用できるようにします:
var zmHub = $.connection.ZmHub; var zmApp = angular.module('zmApp', ['ngRoute', 'ngResource', 'ngSanitize', 'ngMessages', 'ngSVGAttributes']).value('zmHub', zmHub);
6.ホームページ上のコントローラーでメッセージを送信し、次の 2 つのプッシュ エクスペリエンスを提供します。デスクトップ通知はクールです。ブラウザが最小化されていても、デスクトップの右下隅でプロンプトを受け取ることができます (Chrome と Firefox ではサポートされていますが、IE ではサポートされていません)
zmHub.client.broadcastTodo = function (userIds, obj) { //通知下级控制器有待办事项 $scope.$broadcast('todoschanged', obj); //显示桌面通知 if (obj.type == 'new') { //桌面通知标题 var title = '来自[' + obj.data.ApplicantName + ']的申请单'; //申请单类型名称 var formTypeName = DefaultService.getEnumText(17, obj.data.Type); var msg = '[' + formTypeName + ']' + obj.data.Name; //桌面通知方法 NotifyService.Notify('todos', title, msg); } }
下位レベルのコントローラーの受信方法 (それほど多くはありません)。 angularjsのブロードキャストについての説明(わからない場合は公式サイトで確認できます):
//接收推送的待办事项 $scope.$on('todoschanged', function (d, obj) { $scope.$apply(function () { //如果是新增数据,在当前列表中添加一条 if (obj.type == 'new') { $scope.todoApps.unshift(obj.data); } else if (obj.type == 'delete') {//如果是撤销申请,则把当前列表中那条数据删除 for (var j = 0; j < $scope.todoApps.length; j++) { if ($scope.todoApps[j].Id == obj.data.Id) { $scope.todoApps.splice(j, 1); break; } } } }); });
デスクトップ通知サービス:
//桌面通知服务 zmApp.factory('NotifyService', function () { return { Notify: function (icon, title, msg) { // At first, let's check if we have permission for notification // If not, let's ask for it if (window.Notification && Notification.permission !== "granted") { Notification.requestPermission(function (status) { if (Notification.permission !== status) { Notification.permission = status; } }); } var iconPath = '/Content/images/icons/' + (icon || 'info') + '.png'; var options = { lang: 'zh-CN', body: msg, icon: iconPath }; var notify; // If the user agreed to get notified if (window.Notification && Notification.permission === "granted") { notify = new Notification(title, options); } else if (window.Notification && Notification.permission !== "denied") { Notification.requestPermission(function (status) { if (Notification.permission !== status) { Notification.permission = status; } if (status === "granted") { notify = new Notification(title, options); } else { console.log('您禁止了桌面通知,无法推送到您的桌面!'); } }); } else { console.log('您禁止了桌面通知,无法推送到您的桌面!'); } if (notify) { notify.onclose = function (evt) { }; //点击切换到浏览器 notify.onclick = function () { window.focus(); }; } } }; });
デスクトップ通知効果:
概要:
の使い方SignalR によるメッセージのプッシュは一般に比較的単純で、必要な手順はわずか 1 つだけです。また、セルフホストなので、他のサーバーへの依存やデータのセキュリティの問題を心配する必要はありません。試してみてください