【问题标题】:SqlDependency with SignalR user specific具有 SignalR 用户特定的 SqlDependency
【发布时间】:2017-06-02 21:00:29
【问题描述】:

请关注代码:

_布局:

$(function () {
    var connection = $.connection.notificationHub;

    //signalr method for push server message to client
    connection.client.addNotification = function (who) {
        //send notification here
        console.info("Send Notification")
    };

    // Start hub
    $.connection.hub.start().done(function () {
        console.log("SignalR Started")
    });
});

Global.asax.cs:

public class Global : HttpApplication
{
    string con = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        //here in Application Start we will start Sql Dependency
        SqlDependency.Start(con);
    }

    protected void Session_Start(object sender, EventArgs e)
    {
        NotificationComponent NC = new NotificationComponent();
        var currentTime = DateTime.Now;
        HttpContext.Current.Session["LastUpdated"] = currentTime;
        NC.RegisterNotification(currentTime);
    }

    protected void Application_End()
    {
        //here we will stop Sql Dependency
        SqlDependency.Stop(con);
    }
}

控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult MyAction(string parameter)
{
    //Database Notification (Table - Contacts) -Add or Update
    ctx.SaveChanges();
}

NotificationHub:中心

private readonly static ConnectionMapping<string> _connections = new ConnectionMapping<string>();

public static void SendNotification(string who)
{
    IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
    foreach (var connectionId in _connections.GetConnections(who))
    {
        var result = context.Clients.Client(connectionId);
        if (result != null)
        {
            result.addNotification(who);
        }
    }
}

Components.cs:

public void RegisterNotification(DateTime currentTime)
{
    string conStr = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
    string sqlCommand = @"SELECT [ContactID],[ContactName],[ContactNo] from [dbo].[Contacts] where [AddedOn] > @AddedOn";
    //you can notice here I have added table name like this [dbo].[Contacts] with [dbo], its mendatory when you use Sql Dependency
    using (SqlConnection con = new SqlConnection(conStr))
    {
        SqlCommand cmd = new SqlCommand(sqlCommand, con);
        cmd.Parameters.AddWithValue("@AddedOn", currentTime);
        if (con.State != System.Data.ConnectionState.Open)
        {
            con.Open();
        }
        cmd.Notification = null;
        SqlDependency sqlDep = new SqlDependency(cmd);
        sqlDep.OnChange += sqlDep_OnChange;
        //we must have to execute the command here
        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            // nothing need to add here now
        }
    }
}

//After code `ctx.SaveChanges()`, call the code below (50 times):
void SqlDep_OnChange(object sender, SqlNotificationEventArgs e) //<-- Here Problem
{

    //from here we will send notification message to client
    NotificationHub.SendNotification("User1586");
    //...

    //re-register notification
    RegisterNotification(DateTime.Now);

    //HERE -After this line "RegisterNotification(DateTime.Now);", it returns again to the line: "void SqlDep_OnChange(object sender, SqlNotificationEventArgs e)"
}

用户“User1586”正在接收多个通知。 "void SqlDep_OnChange(object sender, SqlNotificationEventArgs e)" 行重复了几次。 如果你有 50 个在线用户,在这条线上做 50 次:

void SqlDep_OnChange(object sender, SqlNotificationEventArgs e)

如果你有 1000 个在线用户,在这条线上做 1000 次:

void SqlDep_OnChange(object sender, SqlNotificationEventArgs e).

换句话说,用户“User1586”收到了多个通知。

我按照这里的例子:http://www.dotnetawesome.com/2016/05/push-notification-system-with-signalr.html

想法是在数据库更新后向特定用户发送通知。

有什么办法吗?

【问题讨论】:

    标签: c# asp.net asp.net-mvc


    【解决方案1】:

    首先,Sql依赖并不知道哪些数据发生了变化。所以你应该在事件处理程序内部查询。如果您想发送与用户 ID 相对应的数据,并且专门针对一个用户,我建议您这样做;

    事件处理程序

    private void SqlDependency_OnChange(object sender, SqlNotificationEventArgs e)
    {
        if (e.Info == SqlNotificationInfo.Insert)
        {
             RecordInfo info = GetLastInsertedRecord(); //Just a custom entity
              if(info.UserId > 0)
                 NotificationHub.SendNotification(info.UserId);
        }
        RegisterNotification(DateTime.Now);
    }
    

    集线器

    public static List<UserConnection> ListUser { get; set; }
    public static void SendNotification(string who)
    {
        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();  
        // Get specific user from connected ones.
        string Id = ListUser.Find(x => x.UserId == who).ConnectionId;
        context.Clients.Client(Id).addNotification(who); // or another data
    }
    //Add every connected users to the list
    public override Task OnConnected()
        {
            ListUser = new List<UserConnection>();
            var us = new UserConnection();
            us.UserId = Context.QueryString["UserId"];
            us.ConnectionId = Context.ConnectionId;
            ListUser.Add(us);
    
            return base.OnConnected();
        }
    

    更新客户端

    $(function () {
        var connection = $.connection.notificationHub;
        //Pass the userId here as querystring  
        $.connection.hub.qs = "UserId=" + $("#labelHoldsUserId").val();
        //signalr method for push server message to client
        connection.client.addNotification = function (who) {
            //send notification here
            console.log(who + " sends message");
        };
    
        // Start hub
        $.connection.hub.start().done(function () {
            console.log("SignalR Started")
        });
    })
    

    【讨论】:

    • ibubi,我有兴趣。
    • 非常感谢
    【解决方案2】:

    似乎 OnChange 处理程序和 SqlDependency 实例都只适用于一个事件。触发事件并取消订阅处理程序后,您需要将处理程序注册到新的 SqlDependency 对象。

    请参阅此处的链接以获取完整详细信息:http://msdn.microsoft.com/en-us/library/a52dhwx7(v=vs.80).aspx

    【讨论】:

    • 看不懂,能给我举个例子吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 2015-05-14
    • 1970-01-01
    相关资源
    最近更新 更多