【问题标题】:Pushing data from SQL Server to Web Application with SignalR使用 SignalR 将数据从 SQL Server 推送到 Web 应用程序
【发布时间】:2012-06-15 14:29:13
【问题描述】:

我的 ASP.NET MVC 4 Web 应用程序正在向客户端显示经常更新的数据。 数据源自外部来源(安装在服务器上的应用程序)并由 SQL Server 2008 R2 处理。

目前的数据流非常传统:客户端从 ASP.NET 轮询,ASP.NET 从 SQL Server 轮询。

为了避免轮询(现在我需要在 Web 应用程序的用户之间进行实时交互),我正在更改推送方法,使用 signalR 向客户端广播数据。 这增加了用户体验的流畅性,也减少了客户端和 ASP.NET 服务器之间轮询的开销。

现在的问题是反转 SSRV 和 ASP.NET 之间的流程:我想以最有效的方式将数据从 SSRV 推送到 ASP.NET

SSRV 正在运行昂贵的查询来导入一些外部数据 - 一旦数据处理完毕,它们也可以通过广播在 Internet 上共享。

我目前的穷人方法:向 Web 应用程序(在 localhost 上)发出 POST Http 请求以发送数据(为此我使用 CLR 函数)。

处理完数据后,我将它们打包到HttpWebRequest,将它们放入Service Broker 中排队以避免影响其他活动,然后我就完成了。

我已经注销了 SqlDependency,因为这会迫使我查询数据 - 这不是一个很大的优势(我会用 localhost HTTP 请求来换取在 SQL Server 上运行的查询)

同时我觉得应该有一个更简洁的方法来做到这一点。

有什么建议吗?

【问题讨论】:

    标签: asp.net-mvc sql-server-2008 signalr server-push


    【解决方案1】:

    嗯, 我意识到 SignalR.Client.NET.35 库有点晚。

    在撰写本文时,它没有打包在 NuGet 中,因此代码必须是来自 GitHub SignalR 项目站点的 downloaded 并作为项目添加到解决方案中(均 SignalR.Client.NETSignalR.Client.NET35 需要)。

    这是最终的解决方案,以防将来可以帮助某人:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
    using System.Data;
    using System.Xml;
    using Microsoft.SqlServer.Server;
    using System.Data.SqlTypes;
    using System.Net;
    using System.IO;
    using System.Xml.XPath;
    using SignalR.Client.Hubs;
    
        internal static HubConnection connectionT = null;
        internal static IHubProxy msgHubT = null;
    
        /// <summary>
        /// allows SSRV to send a message to the Web Socket hub
        /// </summary>
        /// <param name="URL">URL of the Hub</param>
        /// <param name="hubName">Name of the message Hub to be used for broadcasting.</param>
        /// <param name="hubMethod">Hub method to be used for broadcasting.</param>
        /// <param name="message">Message to be broadcasted.</param>
        [SqlFunction()]
        public static void ut_sendMsgToHub(string URL, string hubName, string hubMethod, string message)
        { 
          try
            {
            if (connectionT == null)
            {
                connectionT = new HubConnection(URL.Trim()); // "http://localhost:56844/M2Hub"
            }
            if (msgHubT == null)
            {
                msgHubT = connectionT.CreateProxy(hubName.Trim());//"M2data"
            }
    
                if (!(connectionT.State == SignalR.Client.ConnectionState.Connected 
                    || connectionT.State == SignalR.Client.ConnectionState.Reconnecting
                     || connectionT.State == SignalR.Client.ConnectionState.Connecting))
                    connectionT.Start().Wait();
                msgHubT.Invoke(hubMethod.Trim(), message.Trim()).Wait();//"Send"
            }
            catch (Exception exc)
            {
                SqlContext.Pipe.Send("ut_sendMsgToHub error: " + exc.Message + Environment.NewLine);
            }
        }
    

    注意事项: 连同已编译的 SQL SERVER 2008R2 CLR 库,您必须将以下 dll 放在同一文件夹中:

    • Newtonsoft.Json
    • SignalR.Client.Net35 明显
    • SM 诊断
    • System.Runtime.Serialization
    • System.ServiceModel 在正确的版本中(如果不兼容,请参阅 C:\Windows\assembly 中 GAC 中所述的版本)。
    • System.Threading

    终于在 SQL SERVER 中:

    CREATE ASSEMBLY CLR_Bridge from 'C:\PathToLibraries\Library_CLR.dll' 
    WITH PERMISSION_SET = UNSAFE --UNSAFE required
    CREATE PROCEDURE ut_sendMsgToHub 
    @url nchar(125) ,
    @hubName nchar(75),
    @hubMethod NCHAR(75),
    @message NVARCHAR(MAX)
    AS
    EXTERNAL NAME CLR_Bridge.[LibraryNamespace.CLR_Bridge].ut_sendMsgToHub 
    

    为了调用 ut_sendMsgToHub,我使用了一个服务代理,以便我确信函数执行的任何问题都与处理数据的存储过程分离

    【讨论】:

    • SignalR 的伙计们帮助我就这种针对普通 POST 的方法发表了一些评论 - 你可以阅读线程 here
    • 您是否直接从 sql server 的 clr dll(signalR 服务器)向 signalR 客户端提供数据?这个dll在什么类型的vs项目中?类库还是 Sql Server 数据库项目?
    【解决方案2】:

    你看过SignalR吗?您可以使用它将数据异步推送到您的 UI(尽管它不是真正的推送)。对于您的具体情况,这可能无法接受,但我建议您看一下。可能是你需要的。希望对您有所帮助。

    【讨论】:

    • 正如我上面写的,我已经在使用 SignalR,问题是 SSRV 和 Web 应用服务器之间的数据流,而不是 Web 应用服务器和客户端之间的数据流......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多