Envío de datos de SQL Server a la aplicación web con SignalR

Mi aplicación web ASP.NET MVC 4 muestra datos actualizados con frecuencia al cliente. Los datos se originan en una fuente externa (una aplicación instalada en el servidor) y son procesados ​​por SQL Server 2008 R2.

Actualmente el flujo de datos es bastante tradicional: sondeos de clientes desde ASP.NET, sondeos ASP.NET a su vez desde SQL Server.

Para evitar el sondeo (y ahora que necesito una interacción en tiempo real entre los usuarios de la aplicación web), estoy cambiando el enfoque para empujar, usando signalR para transmitir datos a los clientes. Esto aumenta la fluidez de la experiencia del usuario y también reduce la sobrecarga de sondeo entre los clientes y el servidor ASP.NET.

El problema ahora es invertir el flujo entre SSRV y ASP.NET: me gustaría empujar los datos de SSRV a ASP.NET de la manera más eficiente.

SSRV está ejecutando consultas costosas para importar algunos datos externos, y una vez que los datos se procesan, también están listos para compartir a través de Internet a través de la transmisión.

El enfoque de mi pobre hombre actual: emitir una solicitud POST Http a la aplicación web (en localhost) para enviar los datos (estoy usando una función CLR para eso).

Una vez procesados ​​los datos, los embalo listos para el HttpWebRequest, ponlos en cola en un Service Broker para evitar afectar las otras actividades y listo.

yo he dado de baja SqlDependency como me obligaría a consultar los datos, no es una gran ventaja (cambiaría una solicitud HTTP localhost por una consulta ejecutada en SQL Server)

Al mismo tiempo, siento que debería haber una forma más ordenada de hacer esto.

¿Alguna sugerencia?

preguntado el 12 de junio de 12 a las 17:06

2 Respuestas

Bueno, me di cuenta un poco tarde sobre la biblioteca SignalR.Client.NET.35.

Al momento de escribir, no está empaquetado en NuGet, por lo que el código debe ser descargar desde el sitio del proyecto SignalR de GitHub y agregado como un proyecto a la solución (ambos SignalR.Cliente.NET y SignalR.Client.NET35 necesario).

Aquí está la solución final, en caso de que pueda ayudar a alguien en el futuro:

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

Importante tener en cuenta: junto con la biblioteca compilada SQL SERVER 2008R2 CLR, deberá colocar los siguientes dlls en la misma carpeta:

  • Newtonsoft.Json
  • SignalR.Client.Net35 obviamente
  • SMdiagnóstico
  • System.Runtime.Serialización
  • System.ServiceModel en la versión correcta (consulte la versión como se indica en el GAC en C:\Windows\assembly en caso de incompatibilidades).
  • Sistema.Threading

finalmente en 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 

Para llamar a ut_sendMsgToHub utilizo un intermediario de servicios para estar seguro de que cualquier problema con la ejecución de la función se desvincula de los procedimientos almacenados que procesan los datos.

Respondido 30 ago 12, 06:08

los muchachos de SignalR me ayudaron amablemente con algunos comentarios sobre este enfoque contra POST simple; puede leer el hilo aquí - eddo

¿Está sirviendo datos directamente desde el servidor sql? clr dll (servidor SignalR) a clientes SignalR? ¿En qué tipo de proyecto vs está este dll? ¿Biblioteca de clases o proyecto de base de datos de servidor Sql? - ibubi

Has mirado SeñalR? Puede usarlo para enviar datos de forma asíncrona a su interfaz de usuario (aunque no es un verdadero envío). Esto puede no ser aceptable para su situación específica, pero le sugiero que eche un vistazo. Podría ser lo que necesitas. Espero que ayude.

Respondido el 14 de junio de 12 a las 19:06

como escribí anteriormente, ya estoy usando SignalR, el problema es el flujo de datos entre SSRV y el servidor de la aplicación web, no entre el servidor de la aplicación web y el cliente... - eddo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.