¿Cómo informa un servidor a un cliente WCF WCF sobre los cambios? (Mejor solución luego de sondeo simple, por ejemplo, Comet o largo polling)

StackOverflow https://stackoverflow.com/questions/1700917

Pregunta

  

véase también " WCF empujar al cliente a través de    cortafuegos "

Es necesario disponer de un cliente WCF que se conectan a un servidor de WCF, a continuación, cuando algunos de los datos cambios en el servidor de los clientes necesitan a actualización su pantalla.

Como no es probable que sea un servidor de seguridad entre los clientes y el servidor.

  • Todas las comunicaciones deben ser a través de HTTP
  • El servidor no puede hacer una (física) llamada saliente para el cliente.

Mientras escribo el cliente y el servidor no necesito para limitar la solución a usar solamente jabón, etc.


Busco construida en surport para " sondeo largo " / " Comet " etc


Gracias por la respuesta más informativa de Drew Marsh sobre cómo implementar sondeo largo de WCF. Sin embargo pensé que el principal “punto de venta” de WCF era que se podía hacer este tipo de cosas simplemente mediante la configuración de los canales que se utilizarán en el archivo de configuración. por ejemplo quiero un canal que, lógicamente, pero físicamente dos vías de entrada única.

¿Fue útil?

Solución

Me suena como que ya sabe la respuesta: el uso a largo votación. :) Así que supongo que lo único que queda es para explicar cómo usted puede ser capaz de lograr esto con WCF y de la manera más eficiente posible.


Lo básico:

  1. En primer lugar, decidir cuánto tiempo desea que cada "larga sondeo" que sea. Por mor del argumento que voy a elegir los tiempos de espera 5min.
  2. En el lado del cliente vinculante, cambiar el sendTimeout="00:05:00".
  3. Al igual que el uso de XmlHttpRequest (XHR) por mucho tiempo de votación, cuando el tiempo de espera ocurre realmente, tendrá que detectará y volver a emitir la siguiente solicitud de sondeo. Esto es bastante fácil en WCF porque hay una excepción específica, TimeoutException , que se puede tomar para detectar fácilmente este fue el tema frente a alguna otra excepción.
  4. En función de cómo es el anfitrión de su servicio WCF, tendrá que asegurarse de configurar usted mismo para permitir el procesamiento para un máximo de 5 minutos. Desde una perspectiva de WCF pura usted querrá asegurarse de establecer la receiveTimeout="00:05:00". Sin embargo, si se está hospedando en el interior de ASP.NET que también tendrá que configurar el tiempo de ejecución de ASP.NET para tener un tiempo de espera mayor que se realiza mediante el <httpRuntime executionTimeout="300" /> ( Nota: las medidas son en segundos para este atributo).

Ser eficiente en el cliente

Si acaba de configurar su cliente para llamar de forma sincrónica el servicio y el cliente bloquea durante 5 minutos a la espera de una respuesta, eso no es un uso muy eficiente de los recursos del sistema. Se puede poner estas llamadas en subprocesos en segundo plano, pero que todavía va a masticar un recurso hilo, mientras la llamada es excepcional. La forma más eficaz para hacer frente a esto es utilizar las operaciones asíncronas.

Si va a crear sus contratos de servicio con la mano, sugeriría el registro de salida esta sección en MSDN en OperationContractAttribute.AsyncPattern para obtener más información sobre cómo añadir un BeginXXX / EndXXX método asíncrono par para cada una de sus llamadas. Sin embargo, si usted está utilizando svcutil para generar sus contratos de operación para usted, todo lo que necesita hacer para tener métodos asincrónicos generados es pasar la opción /async en la línea de comandos. Para más detalles sobre este tema, echa un vistazo a este tema síncrona y asíncrona en MSDN .

Ahora que ha van sus operaciones asíncronas definen, el patrón es muy parecido al funcionamiento de XHR. Se llama al método BeginXXX a la que se pasa un AsyncCallback delegado . El método BeginXXX le devolverá un IAsyncResult , que usted puede sostener sobre si desea ser capaz de esperar en la operación (en los escenarios más avanzados) o ignorar, y luego la infraestructura WCF enviará de forma asíncrona la petición al servidor y esperar una respuesta detrás de las escenas. Cuando se recibe una respuesta o se produce una excepción, la devolución de llamada que ha pasado en el método BeginXXX se invocará. Dentro de este método de devolución de llamada es necesario llamar al método EndXXX correspondiente que pasa en el IAsyncResult que se entrega a ti. Durante la llamada al método EndXXX la necesidad de emplear el manejo para hacer frente a cualquier tipo de fallo lógico que haya sucedido durante una llamada al método excepción, pero esto es también el lugar donde ahora sería capaz de coger el TimeoutException hemos hablado antes. Suponiendo que tenga una buena respuesta, los datos serán devueltos al de la EndXXXllama y se puede reaccionar a esos datos en la forma que tenga sentido.

Nota: Una cosa a tener en cuenta acerca de este patrón es la naturaleza de la rosca. Las devoluciones de llamada asincrónicas de WCF serán recibidos en un hilo de la piscina subproceso administrado . Si usted está pensando en actualizar la interfaz de usuario en una tecnología como WPF o WinForms, es necesario asegurarse de que las llamadas Mariscal de nuevo al hilo de interfaz de usuario mediante la Invoke o métodos BeginInvoke.

Ser eficiente en el servidor

Si vamos a estar preocupado por la eficiencia en el cliente, debemos ser doblemente cuando se trata del servidor. Obviamente, este tipo de enfoque pone más demanda en el lado del servidor debido a una conexión debe permanecer abierto y en espera hasta que haya una razón para enviar una notificación al cliente. El reto aquí es que sólo se desea atar el tiempo de ejecución de WCF con el procesamiento de los clientes que se están enviando en realidad un evento. Todo lo demás debe ser sólo dormido, esperando a que se produzca el evento. Por suerte el mismo patrón asincrónico que la utilizamos en el lado del cliente también trabaja en el lado de los servidores. Sin embargo, ahora hay una diferencia importante: ahora debe devolver el IAsyncResult (y por lo tanto un WaitHandle ) a partir del método BeginXXX el cual esperará entonces el tiempo de ejecución de WCF que se señaliza en antes de llamar al método EndXXX.

Usted no encontrar mucho en el camino de la documentación en el interior de MSDN aparte de los enlaces que ya he proporcionado anteriormente y, por desgracia, sus muestras de escritura de un servicio asíncrono son menos útiles. Dicho esto, Wenlong Dong escribió un artículo acerca de la expansión de servicios WCF con el modelo asíncrono hace un tiempo que le recomiendo a la salida.

Más allá de esto, honestamente no puedo dar demasiados consejos sobre la mejor manera de implementar el modelo asíncrono en el lado del servidor para que bcause que depende enteramente de qué tipo de fuente de datos de sus eventos vendrán de en el primer lugar . File I / O? Una cola de mensajes? Una base de datos? Existe otro software propietario con su propio servicio de mensajería que usted está tratando de proporcionar una fachada más? No sé, pero todos le ofreciesen modelos asincrónicos de su propia donde puede llevan a cuestas su propio servicio para que sea lo más eficiente posible.

Receta Actualizado

Dado que esto parece ser una respuesta popular, pensé que debería volver aquí y ofrecer una actualización teniendo en cuenta los recientes cambios en el paisaje. En este punto hay ahora es una biblioteca .NET llamada SignalR que proporciona esta funcionalidad exacta y es sin duda la forma en que recomendaría la implementación de este tipo de comunicación con el servidor.

Otros consejos

Si el servidor podría hacer una conexión de salida a un bus de servicio que podría implament un tipo de llamada. De esta manera el cliente / servidor no necesitaría saber el uno del otro en absoluto, sólo el bus de servicios de confianza. Ver .NET Service Bus

Usted querrá mirar en WSDualHttpBinding

  

El WSDualHttpBinding proporciona la   mismo soporte para los protocolos de servicios Web   como el wsHttpBinding, pero para su uso con   contratos dúplex. WSDualHttpBinding   sólo es compatible con la seguridad SOAP y   requiere de mensajería confiable. Esta   vinculante requiere que el cliente tiene una   URI público que ofrece una devolución de llamada   punto final para el servicio. Esto es   proporcionado por el ClientBaseAddress. UNA   doble unión expone la dirección IP   el cliente para el servicio. El cliente   debe utilizar la seguridad para garantizar que se   sólo se conecta a los servicios que confía.   

Si bien no WCF se podría tratar de usar XMPP para conseguir que la funcionalidad de ir. Hay un artículo sobre InfoQ al respecto y otros sistemas. Mientras que el artículo establece que XMPP no se puede utilizar a través de HTTP, puede al usar BOSH .

Hay bibliotecas .NET disponibles agsXMPP por nombrar uno.

La empresa en la que trabajo está empezando a utilizarlo para empujar las notificaciones de actualización a una solicitud de que se actualice partes de la interfaz de usuario.

Google de " WCF dúplex ". He usado esta utilizando con éxito netTcpBinding (en todos los continentes), pero no estoy seguro sobre basicHttpBinding.

Sin embargo, sí requiere el servidor para volver a llamar al cliente. Si el servidor no está autorizado a hacer esto, la votación puede ser su única opción ...

Si el servidor no puede llamar al cliente (y no debería por lo general) que debe tener el cliente al servidor de votación según lo especificado. ya que tienes WCF fundación ya en su lugar, sólo tiene que añadir una operación para eso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top