2012-06-12 8 views
9

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

Actualmente, el flujo de datos es bastante tradicional: los clientes sondean desde ASP.NET, ASP.NET sondea 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 de push, usando signalR para transmitir datos a los clientes. Esto aumenta la suavidad de la experiencia del usuario y también reduce la sobrecarga del sondeo entre los clientes y el servidor ASP.NET.

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

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

El enfoque de mi pobre actual: emitir una solicitud POST Http a la Aplicación Web (en el servidor local) para enviar los datos (estoy usando una función CLR para eso).

Una vez que los datos se procesan, los preparo listos para el HttpWebRequest, los pongo en una cola de servicios para evitar afectar las otras actividades y listo.

me han cancelado SqlDependency que yo obligaría a una consulta de los datos - no es una gran ventaja (que cambiaría de una solicitud localhost HTTP para una carrera de consulta en SQL Server)

Al mismo tiempo me siento debería haber una manera más ordenada de hacer esto.

¿Alguna sugerencia?

Respuesta

7

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

En el momento de la escritura, que no está envasado en NuGet, por lo que el código debe ser downloaded desde el sitio del proyecto GitHub SignalR y añadido como un proyecto a la solución (tanto SignalR.Client.NET y SignalR. Se requiere Client.NET35).

Aquí está la solución final, en caso de que puede 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 el 2008R2 biblioteca CLR compilado SQL SERVER tendrá que colocar las siguientes dlls en la misma carpeta:

  • Newtonsoft.Json
  • SignalR.Client.Net35 obviamente
  • SMdiagnostics
  • System.Runtime.Serialization
  • System.ServiceModel en la versión correcta (consulte la versión como se indica en la GAC ​​en C: \ Windows \ assembly en caso de incompatibilidades).
  • System.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 ut_sendMsgToHub utilizo un corredor de servicio por lo que estoy seguro de que cualquier problema con la ejecución de la función se desacopla de la procedimientos almacenados que procesan los datos

+1

los chicos de SignalR tener amablemente me ayudó con algunas observaciones sobre este enfoque contra el POST simple: puede leer el hilo [aquí] (https://github.com/SignalR/SignalR/issues/626) – eddo

+0

¿Está sirviendo directamente datos de ** clr dll del servidor sql? ** (servidor de señalR) a los clientes de señalR? ¿Qué tipo de vs proyecto es este dll? ¿Biblioteca de clases o proyecto de base de datos de servidor Sql? – ibubi

1

¿Has mirado SignalR? Puede usarlo para enviar datos de forma asíncrona a su UI (aunque no es un verdadero empuje). Esto puede no ser aceptable para su situación específica, pero le sugiero que eche un vistazo. Puede ser lo que necesitas. Espero que ayude.

+1

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

Cuestiones relacionadas