ホームページ  >  記事  >  バックエンド開発  >  angularJS+asp.net mvc+SignalR はメッセージ プッシュを実装します

angularJS+asp.net mvc+SignalR はメッセージ プッシュを実装します

伊谢尔伦
伊谢尔伦オリジナル
2016-11-26 11:50:561226ブラウズ

背景

OA 管理システムでは、従業員が申請フォームを提出し、そのメッセージがタイムリーな承認のために関係者にリアルタイムで通知され、承認後に結果がユーザーにプッシュされます。

テクノロジーの選択

私が最初に発見したのは firebase だったので、とても興奮しながら推測を始めました。 Firebase の使い方は簡単です。js を引用し、公式 Web サイトのチュートリアルに従うだけで、すぐにプロジェクトに適用できます。翌日プロジェクトを開いたところ、プッシュ機能が動作していないことがわかりました。なぜでしょうか。結局、firebaseの公式サイトが開けないことが分かりました。 。 。 Firebase が Google に乗っ取られたら、中国からもブロックされる可能性はありますか?もしかしたらfirebase自体がハングアップしてしまい、もう使用できなくなってしまっているのかもしれません。 Push 機能を実装するには、Push データを Firebase サーバーに完全に保存する必要があるため、次のような問題が発生します:

1. Firebase への依存度が高すぎる

3.無料版は弱すぎます)

そこで、友人が SignalR というものを勧めてくれました。これは、他のサーバーに依存しない、ASP.NET 開発者向けのメッセージ プッシュ ライブラリです。

使い方

1. nuget で最新バージョンの SignalR を検索して追加します

angularJS+asp.net mvc+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(&#39;,&#39;)).broadcastTodo(app.AuditorIds, new { type = "new", data = app });
    return app;
}

5. Angular モジュールを登録するときにハブを接続し、それを値としてモジュールに渡し、各コントローラーがこの接続を使用できるようにします:

 var zmHub = $.connection.ZmHub;
  var zmApp = angular.module(&#39;zmApp&#39;, [&#39;ngRoute&#39;, &#39;ngResource&#39;, &#39;ngSanitize&#39;, &#39;ngMessages&#39;, &#39;ngSVGAttributes&#39;]).value(&#39;zmHub&#39;, zmHub);

6.ホームページ上のコントローラーでメッセージを送信し、次の 2 つのプッシュ エクスペリエンスを提供します。デスクトップ通知はクールです。ブラウザが最小化されていても、デスクトップの右下隅でプロンプトを受け取ることができます (Chrome と Firefox ではサポートされていますが、IE ではサポートされていません)

zmHub.client.broadcastTodo = function (userIds, obj) {
    //通知下级控制器有待办事项
    $scope.$broadcast(&#39;todoschanged&#39;, obj);
    //显示桌面通知
    if (obj.type == &#39;new&#39;) {
     //桌面通知标题
        var title = &#39;来自[&#39; + obj.data.ApplicantName + &#39;]的申请单&#39;;
        //申请单类型名称
        var formTypeName = DefaultService.getEnumText(17, obj.data.Type);
        var msg = &#39;[&#39; + formTypeName + &#39;]&#39; + obj.data.Name;
     //桌面通知方法
        NotifyService.Notify(&#39;todos&#39;, title, msg);
    }
}

下位レベルのコントローラーの受信方法 (それほど多くはありません)。 angularjsのブロードキャストについての説明(わからない場合は公式サイトで確認できます):

//接收推送的待办事项
$scope.$on(&#39;todoschanged&#39;, function (d, obj) {
    $scope.$apply(function () {
     //如果是新增数据,在当前列表中添加一条
        if (obj.type == &#39;new&#39;) {
            $scope.todoApps.unshift(obj.data);
        }
        else if (obj.type == &#39;delete&#39;) {//如果是撤销申请,则把当前列表中那条数据删除
            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(&#39;NotifyService&#39;, function () {
    return {
        Notify: function (icon, title, msg) {
            // At first, let&#39;s check if we have permission for notification
            // If not, let&#39;s ask for it
            if (window.Notification && Notification.permission !== "granted") {
                Notification.requestPermission(function (status) {
                    if (Notification.permission !== status) {
                        Notification.permission = status;
                    }
                });
            }
            var iconPath = &#39;/Content/images/icons/&#39; + (icon || &#39;info&#39;) + &#39;.png&#39;;
            var options = {
                lang: &#39;zh-CN&#39;,
                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(&#39;您禁止了桌面通知,无法推送到您的桌面!&#39;);
                    }
                });
            }
            else {
                console.log(&#39;您禁止了桌面通知,无法推送到您的桌面!&#39;);
            }
            if (notify) {
                notify.onclose = function (evt) {
                };
                //点击切换到浏览器
                notify.onclick = function () {
                    window.focus();
                };
            }
        }
    };
});

デスクトップ通知効果:

angularJS+asp.net mvc+SignalR はメッセージ プッシュを実装します

概要:

の使い方SignalR によるメッセージのプッシュは一般に比較的単純で、必要な手順はわずか 1 つだけです。また、セルフホストなので、他のサーバーへの依存やデータのセキュリティの問題を心配する必要はありません。試してみてください

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。