2016-06-15 10 views
5

私はasp.net mvcアプリケーションを開発しようとし、またsignalrを使用しようとしています。問題は、私はプロジェクトのユーザーの通知を制御する2つのテーブルがあることです。私は通知テーブルと通知とユーザーテーブルの多くのテーブルであるNotificationUserテーブルを持っています。私は、ユーザーがシステム内の別のユーザーに通知を作成すると、「Hey!New notification received」のような簡単なメッセージでユーザーを確認するポップアップを表示しようとしています。問題ストアドプロシージャSignalRの変更機能が何度も何度もヒットするのはなぜですか?

ALTER PROCEDURE [dbo].[GetNotifications] 

    @userid int 
    AS 
    BEGIN 
    select n.Ntf_Title,Ntf_Description,n.Ntf_Date from dbo.SysNotifications n INNER JOIN dbo.SysNotificationUser u on n.Ntf_ID =u.NtU_NtfID where [email protected] AND NtU_IsRead=0 
    END 

の下にリストされている私はsignalRで使用されるように多くのtimes.Allステップを打つsignalrのjavascriptの変更機能であるハブ

[HubName("signalRHub")] 
public class NtfHub : Hub 
{ 
    [HubMethodName("notifyChanges")] 
    public static void NotifyChanges() 
    { 
     var context = GlobalHost.ConnectionManager.GetHubContext<NtfHub>(); 
     context.Clients.All.notifyChanges(); 
    } 


} 

起動クラス

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     app.MapSignalR(); 

    } 
} 

部分図

最終で
[HttpGet] 
    public ActionResult GetNtf() 
    { 

     //NtfRepo rp = new NtfRepo(this.HttpContext); 
     string connectionString = ConfigurationManager.ConnectionStrings["conn"].ConnectionString; 
     int userid =id; 
     using (SqlConnection sqlcon = new SqlConnection(connectionString)) 
     { 
      using (SqlCommand sqlcom = new SqlCommand("[GetNotifications]", sqlcon)) 
      { 
       sqlcon.Open(); 
       sqlcom.CommandType = CommandType.StoredProcedure; 
       sqlcom.Parameters.AddWithValue("@userid", userid); 
       sqlcom.Notification = null; 
       SqlDependency dependancy = new SqlDependency(sqlcom); 
       dependancy.OnChange += dependancy_OnChange; 
       var reader = sqlcom.ExecuteReader(); 
       var ntf= reader.Cast<IDataRecord>() 
        .Select(e => new PopulateNtfBar() 
        { 
         Title = e.GetString(0), 
         Description = e.GetString(1), 
         TimeDiff = FindDifferenceTime(e.GetDateTime(2)) 
        }).ToList(); 
       return PartialView("~/Views/Shared/CheckNotification.cshtml", ntf); 
      } 
     } 
    } 

、スクリプト

ユーザーはnotification.Whereを作成した場合に非常に多くの時間を打つ
$(function() { 
     var notification = $.connection.signalRHub; 

     // Create a function that the hub can call to broadcast messages. 
     notification.client.notifyChanges = function() { 
      getData(); 
      toastr.warning("Hey,You have Ntf"); 
     }; 

     // Start the connection. 
     $.connection.hub.start().done(function() { 
      getData(); 
     }).fail(function (e) { 
     }); 
    }); 


    function getData() { 
     var tbl = $("#header_notification_bar") 
     $.ajax({ 
      url: '@Url.Action("GetNtf","Home")', 
      contentType: 'application/html ; charset:utf-8', 
      type: 'GET', 
      dataType: 'html' 
     }).success(function (result) { 
      tbl.empty().append(result); 

     }).error(function() { 

     }); 


    } 

notification.client.notifyChangesが問題でしょうか?何か案が?私はそれを最適化することはできません

EDIT 1 私はコントローラでNtfHub.NotifyChangesを呼び出しています。

void dependancy_OnChange(object sender, SqlNotificationEventArgs e) 
    { 
     if (e.Type == SqlNotificationType.Change) 
     { 
      NtfHub.NotifyChanges(); 
     } 
    } 
+0

ここで、NtfHub.NotifyChanges()を呼び出していますか?おそらく、そのコードでは、サーバーメソッドがJavaScriptまたはC#から直接呼び出して複数回呼び出されている可能性があります。そのコードを追加するには[編集]できますか? – Rhumborl

+0

@Rhumborlコードを編集しました – mayk

+0

@Rhumborl while(true)のように打ちました – mayk

答えて

0

私はSqlDependencyは、この機能のために間違ったアプローチだと思いますが、あなたはこの特定の問題をこのように解決しようとすることができます:
は、あなたのコントローラのアクションにパラメータ「subscribeToNotifications」を追加し

public ActionResult GetNtf(bool subscribeToNotifications) 

SqlDependencyを作成します。それが真である場合に限ります。
その後の通知のみハブ上を購読するには、(これは、同じユーザーに対して複数のSqlDependenciesの作成を防止します)開始:

$(function() { 
    var notification = $.connection.signalRHub; 

    // Create a function that the hub can call to broadcast messages. 
    notification.client.notifyChanges = function() { 
     getData(false); 
     toastr.warning("Hey,You have Ntf"); 
    }; 

    // Start the connection. 
    $.connection.hub.start().done(function() { 
     getData(true); 
    }).fail(function (e) { 
    }); 
}); 


function getData(subscribeToNotifications) { 
    var tbl = $("#header_notification_bar") 
    $.ajax({ 
     url: '@Url.Action("GetNtf","Home")' + '?subscribeToNotifications=' + subscribeToNotifications, 
     contentType: 'application/html ; charset:utf-8', 
     type: 'GET', 
     dataType: 'html' 
    }).success(function (result) { 
     tbl.empty().append(result); 

    }).error(function() { 

    }); 
} 

しかし、すべてのページの更新は、まだサーバー側でサブスクリプションを管理することなく、新しいリスナーを作成することに注意して。 2はUSERIDパラメータを省略(サーバアプリの起動時に)単一SqlDependencyを作成することです

オプション - とにかくあなたがにすべてユーザー1がメッセージを持っ関係なく、通知を送っています。

オプション3 - 真の解決策が全くSqlDependencyを取り除くだけ特定のユーザーへの通知を送る取得される(メッセージの受信者)

0

の理由は、あなたがdependancy_OnChangeイベントから脱退していないということですsqldependencyトリガーはワンショット実行であるため、起動するたびに新しいものを購読する必要があります。実行していないものは、以前のイベントハンドラーの購読を中止しているため、新しいものを購読すると、同じトリガのハンドラ。

private void dependency_OnChange(object sender, SqlNotificationEventArgs e) 
{ 
    SqlDependency dependency = sender as SqlDependency; 
    if (dependency != null) dependency.OnChange -= dependency_OnChange; 
    //Recall your SQLDependency setup method here. 
    SetupDependency(); 
} 
+0

あなたの応答に感謝しますが、それはスクリプトの機能を打つことはありませんnot.client.notifyChanges = function(){ getData(); toastr.warning( "ねえ、あなたはNtfを持っています"); };今すぐ – mayk

+0

あなたがそれを必要とすべきではない文脈を取ってみてください、ハブはすでにそれを持っている必要があります。 Clients.All.notifyChanges(); –

関連する問題