I have developed a webpage that connects to the signalR hub hooking into the jquery code with angularjs. The clients are sent a message when a sqldependency.onchange
event occurs, however, for every client connected the message is duplicated to each. So, if two clients are connected, each client receives two messages and so on.
Here are the steps:
- connect two clients to hub
- Make DB change
- sqlDependency.onchange fires
- Call hub function
clients.all.renewProducts()
- Recreate data respository resetting dependency
- Client Console:
"Database SQL Dependency change detected: Update" app.js:44:12 (Twice)
Hub.cs
public static void SignalRGetData(string data)
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<SignalRGetData>();
context.Clients.All.renewData(data);
// Recereate data and sql dependency
new DataRespository().GetData();
}
DataRespository.cs _dependency_OnChange
public void _dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if(e.Info == SqlNotificationInfo.Update)
{
ProductHub.GetProducts("Database SQL Dependency change detected: " + e.Info);
}
}
GetData
public IEnumerable<ProductInventoryDetail> GetData()
{
using(var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DynamicPricing"].ConnectionString))
{
conn.Open();
var reposQuery =
"SELECT [ID], [Program] FROM [DBO].[Detail]";
using(SqlCommand cmd = new SqlCommand(reposQuery, conn))
{
// remove any command object notifications
cmd.Notification = null;
// create dependency
SqlDependency dependency = new SqlDependency(cmd);
dependency.OnChange += new OnChangeEventHandler(_dependency_OnChange);
if (conn.State == System.Data.ConnectionState.Closed)
conn.Open();
// Execute Sql Command
using(var reader = cmd.ExecuteReader())
{
return reader.Cast<IDataRecord>().Select(x => new ProductInventoryDetail(){
ID = x.GetInt32(0),
Program = x.GetInt32(1)
}
}
}
}
}
Angular JavaScript
// Apply jQuery SignalR operations to Angular
app.value('$', $);
app.factory('signalRService', ['$', '$rootScope', function ($, $rootScope) {
var proxy = null;
var initialise = function () {
// Get Connection to SignalR Hub
var connection = $.hubConnection();
// Create a Proxy
proxy = connection.createHubProxy('SignalRData');
// Publish the event when server has a push notification
proxy.on('renewProducts', function (message) {
console.log("Database SQL Dependency change detectedgnalRGetData: " + message);
$rootScope.$emit('renewProducts', message);
});
// Start Connection
connection.start().done(function () {
console.log("Conenction Ready - invoke proxy");
proxy.invoke('SignalRGetData');
});
};
return {
initialise: initialise
}
}]);