【问题标题】:SignalR2 not working in MVC5 using SqlDependencySignalR2 在使用 SqlDependency 的 MVC5 中不起作用
【发布时间】:2018-03-01 05:58:33
【问题描述】:

我在发布这个问题时犹豫不决,因为网上有很多相同的答案但是我的运气不好,没有什么能帮助我。对于我的 Web 应用程序,我需要通知部分,为此我认为使用 SignalR 2。

但它不起作用。以下是完整的代码部分:

==>中心类

[HubName("MyHub")]
public class MyHub : Hub
{
    public static void Show()
    {
        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
        context.Clients.All.displayStatus();
    }
}

==>全局文件

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        SqlDependency.Start(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }

    protected void Application_End()
    {
        SqlDependency.Stop(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
    }
}

==>存储库

public class DAL
{
    public List<DTO.Employee> GetEmployee()
    {
        List<DTO.Employee> l = new List<DTO.Employee>();
        try
        {
            using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
            {
                con.Open();
                using (var cmd = new SqlCommand("select * from employee", con))
                {
                    cmd.Notification = null;
                    SqlDependency dep = new SqlDependency(cmd);
                    dep.OnChange += new OnChangeEventHandler(Dep_OnChange);

                    using (var drd = cmd.ExecuteReader())
                    {
                        while (drd.Read())
                        {
                            l.Add(new DTO.Employee()
                            {
                                Id = Convert.ToInt64(drd["id"]),
                                Name = Convert.ToString(drd["name"])
                            });
                        }
                    }
                }
            }
        }
        catch { }
        return l;
    }

    private void Dep_OnChange(object sender, SqlNotificationEventArgs e)
    {
        if (e.Type == SqlNotificationType.Change)
        {
            MyHub.Show();
        }
    }
}

==> Owin 启动类

[assembly: OwinStartupAttribute(typeof(SignalR2_App1.Startup))]

namespace SignalR2_App1 { public partial class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } } }

==> 查看

<script src="~/Scripts/jquery-1.10.2.min.js"></script>    
<script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="~/signalr/hubs"></script>
<script type="text/javascript">
    $(function () {
        var job = $.connection.MyHub;
        job.client.displayStatus = function () {
            getData();
        }
        $.connection.hub.start();
        getData();
    })
    function getData() {
        $.ajax({
            url: "/data/getdata",
            contentType: "application/json charset=utf-8",
            dataType: "json",
            type: "Post",
            success: function (result) {
                $.each(result, function (e, obj) {
                    $("#tbldata_tbody").append("<tr><td>" + obj.Id + "</td><td>" + obj.Name + "</td></tr>")
                })
            },
            error: function () {
                alert("Error");
            }
        })
    }
</script>
<body>
<table id="tbldata">
    <thead>
        <tr>
            <td>Id</td>
            <td>Name</td>
        </tr>
    </thead>
    <tbody id="tbldata_tbody"></tbody>
</table>

==>动作

[HttpPost]
    public JsonResult GetData()
    {
        DAL.DAL O = new DAL.DAL();
        return Json(O.GetEmployee());
    }

您可以从以下链接下载整个代码:
Code Link

【问题讨论】:

  • 我还检查了link。在 Sql Server 上我运行了这个查询: ALTER DATABASE SignalRDemo SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE;
  • 我也调试了我的代码,发现表中的任何更改都不会触发 Dep_OnChange 事件。为什么?
  • 解决方案: 1. 此代码在 chrome 中运行良好,但在 mozila firefox 中运行不正常。所以代码没有问题。 2、后来发现方法Dep_OnChange中的参数SqlNotificationEventArgs e总是带Subscribe作为值。 3.所以很明显,sql server 端缺少一些东西。 4.最后我发现我跳过了GRANT SUBSCRIBE QUERY NOTIFICATIONS To sa 5.运行之前的查询抛出错误:Cannot find the user 'sa', because it does not exist or you do not have permission. 6.然后我们将其更改为public而不是sa,它很好。
  • 我终于找到了帮助我的文章link

标签: asp.net-mvc-5 signalr signalr-hub sqldependency signalr-2


【解决方案1】:

根据您的代码,我认为您不了解信号器的所有细节。以下是一些提示:

1.在您的中心内,您不需要 GlobalHost.ConnectionsManager

在集线器内,您已经拥有一个 Clients 属性

2。不要自己创建集线器实例!

在你的 DAL 内部你不应该调用

  MyHub.Show();

取而代之的是抓住 HubContext:

GlobalHost.ConnectionManager.GetHubContext&lt;MyHub&gt;().Clients.All.displayStatus();

更好的方法 - 使用强类型集线器:

根据您的代码,我认为您不了解信号器的所有细节。我建议你阅读https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server

例如在集线器上,您应该只定义客户端可以在服务器上调用的方法。为了正确定义服务器可以在客户端上调用的方法,您可以使用“Strongly-Types-Hubs”。看: https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server#stronglytypedhubs

关于 Hub 对象生命周期的背景信息:

https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server:

您不会实例化 Hub 类或从您自己的方法调用其方法 服务器上的代码; SignalR 集线器为您完成的所有工作 管道。 SignalR 每次都会创建一个新的 Hub 类实例 它需要处理集线器操作,例如客户端连接时, 断开连接,或对服务器进行方法调用。

因为 Hub 类的实例是瞬态的,所以不能使用它们 保持从一个方法调用到下一个方法调用的状态。每次 服务器接收来自客户端的方法调用,您的新实例 Hub 类处理消息。通过多个保持状态 连接和方法调用,使用其他一些方法,例如 数据库,或 Hub 类上的静态变量,或不同的类 不是从 Hub 派生的。如果您将数据持久保存在内存中,请使用 Hub 类上的静态变量等方法,数据将是 应用域回收时丢失。

如果您想通过自己运行的代码向客户端发送消息 在 Hub 类之外,您不能通过实例化 Hub 类来做到这一点 例如,但您可以通过获取对 SignalR 的引用来实现 Hub 类的上下文对象。有关详细信息,请参阅如何 稍后从 Hub 类外部调用客户端方法和管理组 在这个话题中。

【讨论】:

  • 感谢分享这么棒的链接。它肯定会有助于改进或获得有关 SignalR 的完整信息。顺便说一句,您建议的更改没有奏效。有几件事情被发现并最终获得了成功。很快就会在这个线程中分享这些内容。
  • @Arjun 很明显,我写的不是一个完整的解决方案,因为那里有很多错误。我的答案只会让你走上正确的道路。:-)。所以答案可能不正确,但我认为它对您有很大帮助....
  • 是的,当然,不仅是我,还有任何会读到这个问题的人。谢谢朋友。
猜你喜欢
  • 1970-01-01
  • 2013-08-31
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多