2017-04-05 43 views
0

我剛剛開始使用SignalR,並根據SO中的不同文章和多個問題設置配置。我已經跟着每一步。我無法弄清爲什麼依賴關係OnChange沒有解僱?SqlDependency.OnChange dependency_OnChange沒有觸發

[HubName("broadcastHub")] 
public class BroadcastHub : Hub 
{ 
    [HubMethodName("sendNotifications")] 
    public Task<object> SendNotifications() 
    { 
     DataTable dt = new DataTable(); 
     using (var connection = new SqlConnection(strConnectionString)) 
     { 
      connection.Open(); 
      using (SqlCommand command = new SqlCommand(query, connection)) 
      { 
       command.Notification = null; 
       SqlDependency dependency = new SqlDependency(command); 
       dependency.OnChange += new OnChangeEventHandler(dependency_OnChange); 
       var reader = command.ExecuteReader(); 
       dt.Load(reader); 
       connection.Close(); 

      } 
     } 
     IHubContext context = GlobalHost.ConnectionManager.GetHubContext<BroadcastHub>(); 
     var json = Newtonsoft.Json.JsonConvert.SerializeObject(dt); 
     return (context.Clients.All.RecieveNotification(json)); 
    } 
    private void dependency_OnChange(object sender, SqlNotificationEventArgs e) 
    { 
     if (e.Type == SqlNotificationType.Change) 
     { 
      SendNotifications(); 
     } 
    } 
} 

它第一次正常工作,我得到預期的數據。但是,當任何變化表是由它不火dependency_OnChange

我也確定了代理服務通過使用以下查詢啓用: -

select is_broker_enabled from sys.databases where name='msdb' 
select is_broker_enabled from sys.databases where name='mydb' 

兩者都是enabled和價值1

查詢我使用SendNotifications是: -

select Id,OXEName,OXEIP IP,ConnectionStatus Status, Case WHEN ConnectedOxeIP IS NULL OR ConnectedOxeIP = '' THEN OXEIP ELSE ConnectedOxeIP END as ConnectedOxeIP from PBXDetail

Java腳本

$(function() { 
    var notifications = $.connection.broadcastHub; 
    notifications.client.recieveNotification = function (response) { 
    }; 
    $.connection.hub.start().done(function() { 
     notifications.server.sendNotifications(); 
    }).fail(function (e) { 
    });    
}); 

Startup.cs

[assembly: OwinStartup(typeof(myNameSpace.Startup))] 
namespace myNameSpace 
{ 
    public class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      app.MapSignalR(new HubConfiguration() { EnableJSONP = true }); 
     } 
    } 
} 

的Global.asax

protected void Application_Start(object sender, EventArgs e) 
{ 
    System.Data.SqlClient.SqlDependency.Start(strConnectionString); 
} 

protected void Application_End(object sender, EventArgs e) 
{ 
    System.Data.SqlClient.SqlDependency.Stop(strConnectionString); 
} 

回答

1

我已經想通了,並張貼作爲一個答案,這樣誰將會面臨此類問題的任何未來的讀者將能夠弄明白。

我調試的代碼,發現我在dependency_OnChange獲得下面的參數與價值觀SqlNotificationEventArgs和那些有:

Info => Invalid 
Type => Subscribe 
Source => Statement 

如果信息無效,這使我知道,有一個問題我查詢。然後我改變了我的查詢語法,如下所示,它工作正常。

select [Id],[OXEName],[OXEIP] as [IP],[ConnectionStatus] as [Status], Case WHEN [ConnectedOxeIP] IS NULL OR [ConnectedOxeIP] = '' THEN [OXEIP] ELSE [ConnectedOxeIP] END as [ConnectedOxeIP] from dbo.PBXDetail 

以下是查詢狀態,我發現:

select * from table // did not work 
select ID from table // did not work 
select [ID] from table // did not work 
select [ID] from dbo.table // Worked 

這樣做,我發現,在每一個頁面刷新dependency_OnChange被髮射多次的頁面刷新後。例如,如果頁面刷新了10次,它將觸發10次。所以我做了以下修改:

[HubMethodName("sendNotifications")] 
public Task<object> SendNotifications() 
{ 
    DataTable dt = new DataTable(); 
    using (var connection = new SqlConnection(strConnectionString)) 
    { 
     connection.Open(); 
     using (SqlCommand command = new SqlCommand(query, connection)) 
     { 
      command.Notification = null; 
      if (ServiceController.dependency == null) 
      { 
       ServiceController.dependency = new SqlDependency(command); 
       ServiceController.dependency.OnChange += new OnChangeEventHandler(dependency_OnChange); 
      } 
      var reader = command.ExecuteReader(); 
      dt.Load(reader); 
      connection.Close(); 
     } 
    } 
    IHubContext context = GlobalHost.ConnectionManager.GetHubContext<BroadcastHub>(); 
    var json = Newtonsoft.Json.JsonConvert.SerializeObject(dt); 
    return (context.Clients.All.RecieveNotification(json)); 
} 

private void dependency_OnChange(object sender, SqlNotificationEventArgs e) 
{ 
    if (e.Type == SqlNotificationType.Change) 
    { 
     if (ServiceController.dependency != null) 
     { 
      ServiceController.dependency.OnChange -= dependency_OnChange; 
      ServiceController.dependency = null; 
     } 
     SendNotifications(); 
    } 
} 

ServiceController的

public static class ServiceController 
{ 
    internal static SqlCommand command = null; 
    internal static SqlDependency dependency = null; 
    internal static bool isCachingEnabled = false; 
} 

的Global.asax

protected void Application_Start(object sender, EventArgs e) 
{ 
    if (!ServiceController.isCachingEnabled) 
    { 
     SqlDependency.Stop(strConnectionString); 
     SqlDependency.Start(strConnectionString); 
    } 
}