使用SignalR将数据从SQL Server推送到Web应用程序

时间:2012-06-12 16:54:16

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

我的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正在运行昂贵的查询来导入一些外部数据 - 一旦数据被处理,它们也可以通过广播在互联网上共享。

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

处理完数据后,我将它们打包准备好HttpWebRequest,将它们排入Service Broker,以避免影响其他活动,我就完成了。

我已经注销了SqlDependency,因为这会强制我查询数据 - 这不是一个很大的优势(我会在SQL Server上运行查询的本地主机HTTP请求权衡)

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

有什么建议吗?

2 个答案:

答案 0 :(得分:7)

那么, 我意识到SignalR.Client.NET.35库有点晚了。

在撰写本文时,它没有打包在NuGet中,因此代码必须是来自GitHub SignalR项目站点的downloaded并作为项目添加到解决方案中(两者都是 SignalR.Client.NET SignalR.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显然
  • SMdiagnostics
  • 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,我使用服务代理,以确保执行该函数的任何问题都与处理数据的存储过程分离

答案 1 :(得分:1)

你看过SignalR了吗?您可以使用它将数据异步推送到UI(尽管这不是真正的推动)。这可能不适合您的具体情况,但我建议您一起来看看。可能是你需要的。希望有所帮助。