2016-06-15 14 views
5

Ich versuche, eine asp.net mvc-Anwendung zu entwickeln und auch Signalgeber zu verwenden. Das Problem ist, dass ich zwei Tabellen habe, die Benutzerbenachrichtigungen im Projekt steuern. Ich habe eine Notification-Tabelle und auch NotificationUser-Tabelle, die viele bis viele Tabelle der Benachrichtigungs- und Benutzertabellen ist. Ich versuche zu erreichen, dass, wenn ein Benutzer eine Benachrichtigung an einen anderen Benutzer im System erstellt, ich versuche, ein Pop-up zu zeigen, das den Benutzer mit einer einfachen Nachricht wie "Hey! Neue Benachrichtigung erhalten" bestätigt. Das Problem ist Javascript Änderungsfunktion von signalr schlagen so viele times.All Schritt i in signalR unterWarum SignalR ändern Funktion viele Male treffen?

genannten Zwecken verwendet werden

die gespeicherte Prozedur

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 

The Hub

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


} 

Die StartUp Klasse

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

    } 
} 

Die Teilansicht

[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); 
      } 
     } 
    } 

At Last, The Script

$(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 so oft treffen, wenn ein Benutzer eine notification.Where ist das Problem schaffen? Irgendeine Idee? Ich kann es nicht optimieren

EDIT 1 Ich rufe NtfHub.NotifyChanges in Controller.

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

Wo rufen Sie 'NtfHub.NotifyChanges()'? Wahrscheinlich wird in diesem Code die Servermethode mehrmals aufgerufen, entweder von JavaScript oder von C#, die sie direkt aufruft. Kannst du [bearbeiten], um diesen Code hinzuzufügen? – Rhumborl

+0

@Rhumborl Ich bearbeitete den Code – mayk

+0

@Rhumborl sein Schlagen wie während (wahr) jetzt – mayk

Antwort

0

Obwohl ich glaube, dass SqlDependency ist falscher Ansatz für diese Funktion, können Sie versuchen, dieses spezielle Problem auf diese Weise zu lösen:
Parameter hinzufügen „subscribeToNotifications“, um Ihre Controller-Aktion

public ActionResult GetNtf(bool subscribeToNotifications) 

erstellen SqlDependency nur wenn es wahr ist.
Dann abonnieren Sie Benachrichtigungen nur auf Hub gestartet (diese Erstellung mehrerer SqlDependencies für denselben Benutzer verhindern):

$(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() { 

    }); 
} 

aber bewusst sein, dass jede Aktualisierung der Seite noch neue Hörer schaffen wird, ohne Abonnement auf Serverseite verwalten .

Option 2 ist Single SqlDependency (auf dem Server App-Start) Weglassen userId Parameter erstellen - auf jeden Fall Sie eine Benachrichtigung an alle Benutzer egal senden, welche die Nachricht bekam.

Option 3 - die wirkliche Lösung ist bei allen SqlDependency loszuwerden und abschicken nur an bestimmte Benutzer (Empfänger der Nachricht)

0

Der Grund dafür ist, dass Sie nicht aus der dependancy_OnChange Veranstaltung abzumelden Ein sqldependency-Trigger ist eine One-Shot-Ausführung. Sie müssen also jedes Mal, wenn er ausgelöst wird, den neuen abonnieren, was Sie nicht tun, ist die Abmeldung vom vorherigen Event-Handler. Wenn Sie also den neuen abonnieren, haben Sie jetzt mehrere Handler für den gleichen Trigger.

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

danke für Ihre Antwort, aber es trifft nicht die Skriptfunktion notification.client.notifyChanges = function() { getData(); toastr.warning ("Hey, Du hast NTF"); }; jetzt – mayk

+0

Versuchen Sie, den Kontext aus, Sie sollten es nicht brauchen, sollte der Hub es bereits haben. Clients.Alle.notifyChanges(); –

Verwandte Themen