我的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请求权衡)
与此同时,我觉得应该有一个更简洁的方法来做到这一点。
有什么建议吗?
答案 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放在同一个文件夹中:
最后在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(尽管这不是真正的推动)。这可能不适合您的具体情况,但我建议您一起来看看。可能是你需要的。希望有所帮助。