使用SignalR和SqlDependency推送新消息

时间:2015-04-16 14:33:11

标签: c# sql-server signalr sqldependency

我有一个大表,其中包含通常每秒插入一些新项目的项目。我想构建一个实时应用程序,用户可以订阅某些类型的项目,并在插入某种类型的项目时提供实时反馈。

首先,我用过 http://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency但它缺少一些我不确定如何实施的关键部分。

跟踪哪些邮件推送到哪些客户端的最佳方法是什么?如何跟踪已发送的消息,而无需更新"推送"每次收到更新时都会标记?

2 个答案:

答案 0 :(得分:1)

您可以使用SqlDependency类的开源实现 - SqlDependencyEx。它使用数据库触发器和本机Service Broker通知来接收有关表更改的事件。您正在寻找的此组件does exactly the same functionality的测试项目。这是一个用法示例:

int changesReceived = 0;
using (SqlDependencyEx sqlDependency = new SqlDependencyEx(
          TEST_CONNECTION_STRING, TEST_DATABASE_NAME, TEST_TABLE_NAME)) 
{
    sqlDependency.TableChanged += (o, e) => changesReceived++;
    sqlDependency.Start();

    // Make table changes.
    MakeTableInsertDeleteChanges(changesCount);

    // Wait a little bit to receive all changes.
    Thread.Sleep(1000);
}

Assert.AreEqual(changesCount, changesReceived);

使用SqlDependecyEx,您可以单独监视INSERT,DELETE,UPDATE并在事件args对象中接收实际更改的数据(xml)。希望这有帮助。

答案 1 :(得分:0)

SignalR在集线器中提供Context.ConnectionId。您可以将其用作集合中的键,以跟踪已发送的项目。

以下是我写的日志聊天应用程序的示例:

public class PushNotificationHub : Hub {        

    public void Send(string name, string message) {
        ChatService.ChatUsers[Context.ConnectionId].AddMessage(message);
        Clients.All.addMessage(name, message);
    }

    public override Task OnConnected() {
        ChatService.Current.LogMessage($"Client connected: {Context.ConnectionId}");
        ChatService.ChatUsers.Add(Context.ConnectionId, new Common.ChatUser(Context.QueryString["name"]));

        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled) {
        //Application.Current.Dispatcher.Invoke(() => ((MainWindow)Application.Current.MainWindow).LogMessage($"Client disconnected: {Context.ConnectionId}"));
        ChatService.Current.LogMessage($"Client disconnected: {Context.ConnectionId}");
        ChatService.Current.LogMessage(ChatService.ChatUsers[Context.ConnectionId].PrintLog());

        return base.OnDisconnected(stopCalled);
    }
}