tutorial español ejemplo crear .net wcf design-patterns comet long-polling

.net - español - ¿Cómo informa un servidor WCF a un cliente de WCF sobre los cambios?(Mejor solución que una encuesta simple, p. Ej. Comet o larga encuesta)



wcf c# ejemplo (5)

Google para " WCF duplex ". Lo he usado con éxito usando netTcpBinding (en todos los continentes), pero no estoy seguro sobre basicHttpBinding.

Sin embargo, requiere que el servidor devuelva la llamada al cliente. Si el servidor no puede hacer esto, la votación puede ser su única opción ...

ver también " Empuje de WCF al cliente a través del firewall "

Necesito tener un cliente WCF que se conecte a un servidor WCF, luego cuando algunos de los cambios de datos en el servidor los clientes necesitan actualizar su pantalla.

Como es probable que haya un firewall entre los clientes y el servidor.

  • Todas las comunicaciones deben realizarse a través de HTTP
  • El servidor no puede realizar una llamada saliente (física) al cliente.

Como estoy escribiendo tanto el cliente como el servidor, no necesito limitar la solución a solo usar jabón, etc.

Estoy buscando construido en surport para " larga votación " / " Comet ", etc.

Gracias por la respuesta más informativa de Drew Marsh sobre cómo implementar largas encuestas en WCF. Sin embargo, pensé que el principal "punto de venta" de WCF era que podía hacer este tipo de cosas simplemente configurando los canales que se usarían en el archivo de configuración. Por ejemplo, quiero un canal que, lógicamente, sea bidireccional pero solo físicamente entrante.


Me parece que ya sabes la respuesta: utiliza largas encuestas. :) Así que supongo que lo único que queda por explicar es cómo podrías lograr esto con WCF y de la manera más eficiente posible.

Los basicos:

  1. Primero, decida cuánto tiempo quiere que sea cada "encuesta larga". Por el bien de los argumentos, voy a elegir 5 minutos de tiempo de espera.
  2. En el enlace del lado del cliente, cambie sendTimeout="00:05:00" .
  3. Al igual que con XmlHttpRequest (XHR) para un sondeo largo, cuando realmente se produce el tiempo de espera, deberá detectarlo 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 puedes detectar para detectar fácilmente que este fue el problema vs. alguna otra excepción.
  4. Dependiendo de cómo hospede su servicio WCF, deberá asegurarse de configurarlo para permitir el procesamiento por hasta 5 minutos. Desde una perspectiva pura de WCF, querrás asegurarte de configurar el receiveTimeout="00:05:00" . Sin embargo, si está alojando dentro de ASP.NET también necesitará configurar el tiempo de ejecución de ASP.NET para tener un tiempo de espera más alto que se realiza usando <httpRuntime executionTimeout="300" /> ( nota: las medidas están en segundos para este atributo).

Ser eficiente en el cliente

Si solo configura su cliente para que llame de manera síncrona al servicio y el cliente bloquee durante 5 minutos mientras espera una respuesta, ese no es un uso muy eficiente de los recursos del sistema. Podrías poner estas llamadas en hilos de fondo, pero eso aún masticará un recurso de hilo mientras la llamada está pendiente. La forma más eficiente de lidiar con esto es usar operaciones asincrónicas.

Si está creando sus contratos de servicio a mano, le sugiero que consulte esta sección en MSDN en OperationContractAttribute.AsyncPattern para obtener detalles sobre cómo agregar un BeginXXX EndXXX async BeginXXX / EndXXX para cada una de sus llamadas. Sin embargo, si está utilizando svcutil para generar sus contratos de operación, todo lo que necesita hacer para generar métodos asíncronos es pasar la opción /async en la línea de comando. Para obtener más detalles sobre este tema, consulte el tema Sincrónico y Asíncrono en MSDN .

Ahora que has definido tus operaciones de sincronización, el patrón es muy parecido a trabajar con XHR. Llama al método BeginXXX al que pasa un delegado AsyncCallback . El método BeginXXX le devolverá un IAsyncResult , que puede conservar si desea poder esperar en la operación (en escenarios más avanzados) o ignorar, y luego la infraestructura de WCF enviará la solicitud al servidor de manera asíncrona y esperará para una respuesta detrás de escena. Cuando se recibe una respuesta o se produce una excepción, se invocará la devolución de llamada que pasó al método BeginXXX . Dentro de este método de devolución de llamada, debe llamar al método EndXXX correspondiente que pasa en IAsyncResult que se le entregó. Durante la llamada al método EndXXX necesita emplear el manejo de excepciones para tratar cualquier tipo de falla lógica que pueda haber ocurrido al llamar al método, pero aquí también es donde ahora podría captar la TimeoutException que hablamos anteriormente. Suponiendo que hayas obtenido una buena respuesta, los datos serán devueltos por la llamada a EndXXX y puedes reaccionar a esos datos de cualquier forma que tenga sentido.

NOTA: Una cosa a tener en cuenta acerca de este patrón es la naturaleza del enhebrado. Las devoluciones de llamada asincrónicas de WCF se recibirán en un subproceso del grupo de subprocesos administrados . Si planea actualizar la interfaz de usuario en una tecnología como WPF o WinForms, debe asegurarse de coordinar las llamadas al hilo de la interfaz de usuario con los métodos Invoke o BeginInvoke .

Ser eficiente en el servidor

Si vamos a estar preocupados por la eficiencia en el cliente, deberíamos hacerlo doblemente en lo que respecta al servidor. Obviamente, este tipo de enfoque genera más demanda en el lado del servidor porque una conexión debe permanecer abierta y pendiente hasta que haya una razón para enviar una notificación al cliente. El desafío aquí es que solo desea vincular el tiempo de ejecución de WCF con el procesamiento de los clientes a los que realmente se envía un evento. Todo lo demás debería estar dormido, esperando a que ocurra el evento. Afortunadamente, el mismo patrón de sincronización que acabamos de usar en el lado del cliente también funciona en el lado del servidor. Sin embargo, ahora hay una gran diferencia: ahora debe devolver el IAsyncResult (y por lo tanto un WaitHandle ) del método BeginXXX que el tiempo de ejecución de WCF esperará para que se le EndXXX una EndXXX antes de llamar a su método EndXXX .

No encontrará mucho en el camino de la documentación dentro de MSDN aparte de los enlaces que ya he proporcionado anteriormente y, desafortunadamente, sus muestras al escribir un servicio asincrónico no son útiles. Dicho esto, Wenlong Dong escribió un artículo sobre la ampliación de los servicios de WCF con el modelo asíncrono hace algún tiempo que recomiendo encarecidamente que lo revises.

Más allá de esto, sinceramente, no puedo dar demasiados consejos sobre cómo implementar mejor el modelo asíncrono del lado del servidor, ya que depende en primer lugar del tipo de fuente de datos de la que vendrán sus eventos en primer lugar. Archivo de E / S? ¿Una cola de mensajes? Una base de datos? ¿Algún otro software de propiedad con su propio servicio de mensajería que está tratando de proporcionar una fachada? No lo sé, pero todos deberían ofrecer sus propios modelos asíncronos en los que pueda utilizar su propio servicio para hacerlo lo más eficiente posible.

Receta actualizada

Dado que esta parece ser una respuesta popular, pensé que debería volver aquí y proporcionar una actualización dados los cambios recientes en el panorama. En este punto, ahora hay una biblioteca .NET llamada SignalR que proporciona esta funcionalidad exacta y definitivamente es la forma en que recomendaría implementar cualquier comunicación con el servidor.


Si bien no es WCF, podrías intentar usar XMPP para que esa funcionalidad funcione. Hay un artículo sobre InfoQ sobre él y otros sistemas. Si bien el artículo indica que XMPP no se puede usar a través de HTTP, puede hacerlo al usar BOSH .

Hay bibliotecas .NET disponibles agsXMPP para nombrar una.

La compañía donde trabajo está empezando a usarla para enviar notificaciones de actualización a una aplicación para que actualice partes de la interfaz de usuario.


Si el servidor no puede llamar al cliente (y no debería hacerlo normalmente), debe hacer que el cliente interrogue al servidor como usted especificó. ya que tiene la base de WCF en su lugar, simplemente agregue una operación para eso.


Si el servidor puede realizar una conexión de salida a un bus de servicio, puede implantar un tipo de devolución de llamada. De esta forma, el cliente / servidor no necesitaría conocerse el uno del otro, solo el bus de servicio dependiente. Ver .NET Service Bus

Deberá consultar WSDualHttpBinding

WSDualHttpBinding proporciona el mismo soporte para protocolos de servicios web que WSHttpBinding, pero para usar con contratos dúplex. WSDualHttpBinding solo es compatible con la seguridad SOAP y requiere mensajería confiable. Este enlace requiere que el cliente tenga un URI público que proporcione un punto final de devolución de llamada para el servicio. Esto es proporcionado por ClientBaseAddress. Un enlace doble expone la dirección IP del cliente al servicio. El cliente debe usar la seguridad para asegurarse de que solo se conecte a los servicios en los que confía.