【问题标题】:Database Update Not Reflected in Browser using SignarlR使用 SignarlR 未在浏览器中反映数据库更新
【发布时间】:2016-01-18 13:22:41
【问题描述】:

我是 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 类

    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();
        }
    }
}

【问题讨论】:

  • 可以分享一下hub代码吗?消息实际上是通过发送的吗?
  • public void NotifyAllClients(string msg) { IHubContext context = GlobalHost.ConnectionManager.GetHubContext(); context.Clients.All.displayNotification(msg); }
  • 我想这是您对 SqlDependency 的使用不起作用....我从未使用过它们,但是:1)您不必启动 Sql Dependency 吗? 2)我看不到 SendNotifications 是如何被调用的(它设置了依赖)
  • @thab: 确认,你是对的,case 不再是问题了。
  • 这可能是实例化的问题吗?为什么SendNotifications 实例化集线器类?这应该由 SignalR 进程隐式完成,不是吗?

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


【解决方案1】:

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

context.Clients.All.DisplayNotification(msg);

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

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

[...] 此外,SignalR 使用驼峰式方法创建集线器代理,如 在 JavaScript 中是合适的,所以在 服务器将在客户端代理中称为 sendMessage。

【讨论】:

  • 嗯,我认为这两种模式都被 SignalR 接受(至少在 v2.2 中)。这两种情况我都用过,效果很好
  • 已确认,在 v2 中不再是问题
【解决方案2】:

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

不支持使用不是由 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 单独寻址。

【讨论】:

  • 示例不正是这样吗?他不使用 Clients.All - 他也使用 GetHubContext 命令。唯一的区别是使用静态修饰符 - 这是一个好主意,但它会更好吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
  • 2020-08-14
  • 2017-07-24
  • 1970-01-01
  • 2021-09-08
  • 2016-09-20
相关资源
最近更新 更多