2016-06-15 1 views
5

Я пытаюсь разработать приложение asp.net mvc, а также пытаюсь использовать signalr. Проблема в том, что у меня есть две таблицы, которые контролируют пользовательские атрибуты в проекте. У меня есть таблица уведомлений, а также таблица NotificationUser, в которой много таблиц уведомлений и пользовательских таблиц. Я стараюсь, чтобы, если пользователь создает уведомление другому пользователю в системе, я пытаюсь показать всплывающее окно, которое подтверждает пользователя простым сообщением типа «Привет! Новое уведомление получено». Проблема Javascript функции изменения signalr удара так много шага times.All я использовал в signalR перечисленного нижеПочему функция изменения сигнала 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 

ступицу

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

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 поражая так много раз, если пользователь создать notification.Where проблема? Есть идеи? Я не могу его оптимизировать

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 i отредактировал код – mayk

+0

@Rhumborl его ударить как while (true) now – 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 является создание единого SqlDependency (при запуске приложения сервера) опуская параметр USERID - в любом случае вы не отправляете уведомление все пользователей независимо от того, какой из них получил сообщение.

Вариант 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

благодарим вас за ответ, но он не нажимает на функцию скрипта notification.client.notifyChanges = function() { getData(); toastr.warning («Эй, у вас есть Ntf»); }; теперь – mayk

+0

Попробуйте воспользоваться контекстом, вам он не понадобится, хаб должен уже иметь его. Clients.All.notifyChanges(); –

Смежные вопросы