使用SignarlR在浏览器中未反映数据库更新

时间:2016-01-18 13:22:42

标签: c# jquery asp.net-mvc model-view-controller signalr

我是SignalR的新手。当我实现以下代码时,数据库更改不会同时反映在浏览器中。

Javascript代码

    $(function () {
        var notify = $.connection.notificationsHub;

        notify.client.displayNotification = function (msg) {
            console.log(msg);
            $("#newData").html(msg);
        };

        // Start the connection.
        $.connection.hub.start().done(function () {
            alert("connection started");
        }).fail(function (e) {
            alert(e);
        });

        //$.connection.hub.start();
    });

C#代码  NotificationsHub Class

    public void NotifyAllClients(string msg)
    {
        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationsHub>();
        context.Clients.All.displayNotification(msg);
    }

    public void SendNotifications()
    {
        string message = string.Empty;
        string conStr = ConfigurationManager.ConnectionStrings["MvcDemoDb"].ConnectionString;

        using (SqlConnection connection = new SqlConnection(conStr))
        {
            string query = "SELECT [Message] FROM [dbo].[Messages]";

            using (SqlCommand command = new SqlCommand(query, connection))
            {
                command.Notification = null;
                SqlDependency dependency = new SqlDependency(command);
                dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
                connection.Open();
                SqlDataReader reader = command.ExecuteReader();

                if (reader.HasRows)
                {
                    reader.Read();
                    message = reader[0].ToString();
                }
            }
        }
        NotificationsHub nHub = new NotificationsHub();
        nHub.NotifyAllClients(message);
    }

    private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
    {
        if (e.Type == SqlNotificationType.Change)
        {
            SendNotifications();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

尝试使用客户端的服务器端方法调用大写,即使它在客户端开始小写:

context.Clients.All.DisplayNotification(msg);

检查生成的代理以查看完成的方法映射,这是我发现大写问题的地方。

Misspelled method, incorrect method signature, or incorrect hub name涵盖了这一点,代理使用camelCase:

  

[...]此外,SignalR使用驼峰式方法创建集线器代理,如   适用于JavaScript,所以一个名为SendMessage的方法就可以了   服务器将在客户端代理中调用sendMessage。

答案 1 :(得分:0)

我通过尝试从同一个应用程序的代码中实例化集线器类来测试与您所做的类似的场景,尝试调用客户端方法导致异常(我希望您遇到同样的问题):

  

不支持使用HubPipeline未创建的Hub实例。

从概念上讲,我认为你不能实例化集线器并使用它,HubPipeline隐含地实例化它。从这里你有两种可能性IMO:

管理您的中心实例,将静态实例保存到上下文中,如下所示:

private static IHubContext hub = GlobalHost.ConnectionManager.GetHubContext<NotificationsHub>();

public static void NotifyAllClients(string message)
{
    hub.Clients.All.NotifyAllClients(message);
}

这样您就可以使用HubPipeline创建的实例,并且仍然可以从您的应用上下文访问中心方法。

或者作为一种解决方法,您可以将逻辑分开,并使代码单独以hub client作为https://jsfiddle.net/03o910s7/