<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Angel "Java" Lopez : C Sharp, Decentralized Software Services</title><link>http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/Decentralized+Software+Services/default.aspx</link><description>Tags: C Sharp, Decentralized Software Services</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Web Crawler distribuido usando AjMessages</title><link>http://msmvps.com/blogs/lopez/archive/2009/03/10/web-crawler-distribuido-usando-ajmessages.aspx</link><pubDate>Tue, 10 Mar 2009 01:07:04 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1677100</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1677100</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/03/10/web-crawler-distribuido-usando-ajmessages.aspx#comments</comments><description>&lt;p&gt;En Enero pasado, actualicé mi proyecto AjMessages para que soporte comunicación usando DSS/CCR&amp;nbsp;y Windows Communication Foundation. AjMessage puede ejecutarse de forma distribuida, enviando mensajes desde un nodo lógico a otro. Los nodos lógicos pueden albergarse en una o más máquinas física. Más información sobre AjMessages en:&lt;/p&gt; &lt;p&gt;&lt;a title="AjMessages- a message processor" href="http://ajlopez.wordpress.com/2007/10/18/ajmessages-a-message-processor/"&gt;AjMessages- a message processor&lt;/a&gt;&lt;br /&gt;&lt;a href="http://ajlopez.wordpress.com/2008/10/08/distributed-applications-with-ajmessages-using-dssccr/" target="_blank"&gt;Distributed Applications with AjMessages using DSS/CCR&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2008/10/10/aplicaciones-distribuidas-con-ajmessages-usando-dss-ccr.aspx" target="_blank"&gt;Aplicaciones Distribuidas con AjMessages usando DSS/CCR&lt;/a&gt;&lt;br /&gt;&lt;a title="AjMessages- hacia un procesador de mensajes" href="http://msmvps.com/blogs/lopez/archive/2007/10/22/ajmessages-hacia-un-procesador-de-mensajes.aspx"&gt;AjMessages- hacia un procesador de mensajes&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Pueden descargar el código fuente desde&lt;/p&gt; &lt;p&gt;&lt;a title="ajmessages" href="http://www.codeplex.com/ajmessages"&gt;http://www.codeplex.com/ajmessages&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Tenía la idea de escribir un procesador de mensajes distribuidos. Hace unos años, escribí mi primer intento, llamado AjServer&lt;/p&gt; &lt;p&gt;&lt;a title="Hacia el AjServer" href="http://msmvps.com/blogs/lopez/archive/2006/07/20/105318.aspx"&gt;Hacia el AjServer&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Luego, encontré al proyecto &lt;a title="Fabriq" href="http://ajlopez.wordpress.com/2007/10/14/remember-fabriq/"&gt;Fabriq&lt;/a&gt;, estudiando sus ideas e implementación. En ese proyecto,&amp;nbsp;hay manejadores (handlers) lógicos de mensajes, que pueden instalarse de modo distribuido, de forma transparente, cambiando la información de configuración:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/fabriq01.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;En el&amp;nbsp;2007, escribí la primera versión de AjMessages, como prueba de concepto: pude reproducir bastante de las ideas de Fabriq, y a la vez, elevar el nivel de abstracción de algunos puntos, para conseguir mayor flexibilidad. Fabriq estaba más orientado a SOA. AjMessages se orienta a mensajes arbitrarios, que coordinados, pueden funcionar en una aplicación en grilla.&lt;/p&gt; &lt;p&gt;La solución actual de AjMessages es:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/AjMessages01.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Hay un proyecto núcleo, y dos proyectos de transporte: uno para soporte de WCF, y otro que se basa en DSS/CCR (tecnologías de Microsoft Robotics). Si no tienen DSS/CCR instalado, pueden remover los proyectos que lo referencia. El núcleo de AjMessages está lib de dependencias de esas tecnologías.&lt;/p&gt; &lt;p&gt;AjMessages.SampleApp contiene un simple manejador de mensajes: un decrementador de enteros, que toma un mensaje de entrada, con un contenido entero, lo decrementa, y produce un nuevo mensaje.&lt;/p&gt; &lt;p&gt;En cambio,&amp;nbsp;AjMessages.WebCrawler implementa&amp;nbsp;el mensaje y manejadores de mensajes para armar un web crawler distribuido. Pueden ejecutarlo desde una sola máquina, o en varias.&lt;/p&gt; &lt;p&gt;Cara AjMessages tiene:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Body&lt;/strong&gt;: un contenido arbitrario&lt;br /&gt;&lt;strong&gt;Headers&lt;/strong&gt;: información adicional, por clave/valor.&lt;br /&gt;&lt;strong&gt;Action&lt;/strong&gt;: describe el destino del mensaje, usando un patrón Aplicación/Nodo/Acción&lt;/p&gt; &lt;p&gt;(más detalle en &lt;a title="AjMessages- a message processor" href="http://ajlopez.wordpress.com/2007/10/18/ajmessages-a-message-processor/"&gt;&lt;a title="AjMessages- hacia un procesador de mensajes" href="http://msmvps.com/blogs/lopez/archive/2007/10/22/ajmessages-hacia-un-procesador-de-mensajes.aspx"&gt;AjMessages- hacia un procesador de mensajes&lt;/a&gt;&lt;/a&gt;)&lt;/p&gt; &lt;p&gt;Exploremos el ejemplo de web crawler. Esta aplicación está compuesta de nodos, que pueden ser orquestado para visitar una página web, tomar de esa página todos los enlaces relacionados, y volver a tomar esas páginas. Para que no sea un proceso infinito, la visita de páginas se limita al sitio inicial, y hasta un nivel de profundidad. La aplicación puede ser descripta lógicamente con este diagrama:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/webcrawler01.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;El primer mensaje se envía al nodo Controller, a su acción Dispatch. Ese primer mensaje contiene la dirección de la página a visitar. El mensaje es enriquecido, y pasado al nodo Controller, acción Resolve. Este nodo está a cargo de mantener la lista de páginas ya visitadas, y de controlar la profundidad de exploración. Si el enlace recibido es aprobado, entonces el mensaje es enviado al nodo Downloader, acción Download. El contenido de la página es recuperado, agregado al mensaje, y reenviado al nodo Harvester, a su acción&amp;nbsp;Harvest. Esta acción analiza el contenido de la página, y emite&amp;nbsp;varios mensajes, uno por&amp;nbsp;cada enlace encontrado. El receptor de esos nuevos enlaces es el nodo Resolver, en su acción Resolve. Así, el proceso continua hasta visitar todas las páginas (con un límite en la profundidad a explorar).&lt;/p&gt; &lt;p&gt;Esta aplicación se puede describir en un archivo de configuración XML, como por ejemplo:&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:a3a0de01-755f-4538-96e5-153042196cee" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;AjMessages&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Dispatcher&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Handler &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;DispatcherHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages.WebCrawler.Handlers.Dispatcher, AjMessages.WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Action &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Dispatch&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Handler&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;DispatcherHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Harvester&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Handler &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;HarvesterHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages.WebCrawler.Handlers.Harvester, AjMessages.WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Action &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Harvest&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Handler&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;HarvesterHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Downloader&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Handler &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;DownloaderHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages.WebCrawler.Handlers.Downloader, AjMessages.WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Action &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Download&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Handler&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;DownloaderHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Controller&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Handler &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;ResolverHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages.WebCrawler.Handlers.Resolver, AjMessages.WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Action &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Resolve&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Handler&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;ResolverHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;AjMessages&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Un aplicación, entonces, está compuesta de nodos lógicos. Cada nodo puede ser visto como una clase lógica. Cada nodo puede manejar acciones, que son los puntos destinos de los mensajes. Una acción puede&amp;nbsp;estar compuesta de uno o varios pasos. Este es el punto de extensibilidad de la aplicación: deben proveer los pasos, el manejador de mensaje, y escribir el archivo de configuración que orquestre el procesamiento de los mensajes.&lt;/p&gt;
&lt;p&gt;Pero una cosa es la aplicación, y otra es su distribución en máquinas físicas. Pueden tener dos hosts, e instalar diferentes nodes en cada uno:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/webcrawler02.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;En este diagrama, el Dispatcher y el Resolver están en un hosts, mientras que el Downloader y el Harvester están en otro. Pero Uds. pueden poner Harverstes en cada hosts,&amp;nbsp;o en veinte máquinas.&amp;nbsp;Queda en&amp;nbsp;Uds. cómo distribuir la carga del trabajo. Cuando un mensaje&amp;nbsp;es enviado&amp;nbsp;a un destino (Aplicación/Nodo/Acción),&amp;nbsp; AjMessage lo reenvía a un host apropiado, que contenga un nodo capaz de procesar el mensaje.&lt;/p&gt;
&lt;p&gt;La distribución de nodos lógicos en un host físico se define via configuración, por ejemplo:&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:17c1d13e-1e21-4d39-a87d-3e3a2b0a07a4" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;AjMessages&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Host &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Server1&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Address&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;http://localhost:50002/AjMessages&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Activate&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Administration&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Controller&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Dispatcher&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Harvester&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Downloader&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Host&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;

  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Host &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Server2&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Address&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;http://localhost:50003/AjMessages&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Administration&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Dispatcher&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Harvester&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Downloader&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Host&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;AjMessages&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Ejecutando el ejemplo Web Crawler&lt;/h3&gt;
&lt;p&gt;Pueden probar el programa, lanzando dos hosts, en la misma máquina. Hay que ejecutar el programa de consola AjMessage.Console. Al comenzar esta aplicación, podemos ingresar el comando&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;fork&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Este comando lanza un segundo host. Ahora, podemos configurar los dos hosts. En el primero, ingresamos:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;load ConfigurationServer1.xml&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Este archivo carga la aplicación AjMessage inicial (es una aplicación más dentro de &amp;quot;la grilla&amp;quot;), y define un endpoint WCF para escuchar mensajes de otros posibles hosts. Ahora, en la misma consola, ingresamos:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;load ConfigurationWebCrawler.xml&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Este comando carga la definición de la aplicación Web Crawler, con sus nodos lógicos (no hay información de deploy todavía). El tercer comando, define la distribución física de hosts:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;load ConfigurationWebCrawlerNode1.xml&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Ahora, volvamos a la segunda consola. Ahí, ingresamos los comandos:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;load ConfigurationServer2.xml&lt;br /&gt;load ConfigurationWebCrawler.xml&lt;br /&gt;load ConfigurationWebCrawlerNode2.xml&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Estamos listos para lanzar el primer web crawling. Vamos a la primera consola, e ingresamos:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;send WebCrawler/Dispatcher/Dispatch &lt;/font&gt;&lt;a href="http://ajlopez.zoomblog.com"&gt;&lt;font face="Consolas"&gt;http://ajlopez.zoomblog.com&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El programa comienza a trabajar, en AMBAS consolas. Una típica salida de la primera consola:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/webcrawler03.png" alt="" /&gt; &lt;/p&gt;
&lt;h3&gt;Próximos pasos&lt;/h3&gt;
&lt;p&gt;Debería arreglar algunos problemas en el transporte DSS/CCR (actualmente, puede ejecutar una aplicación simple como el decrementador de enteros, pero no con el web crawler). Dos puntos para implementar:&lt;/p&gt;
&lt;p&gt;- Configuración remota de nodos&lt;br /&gt;- Distribución de los manejadores de mensajes (sus&amp;nbsp;.dlls)&amp;nbsp;a los nodos&amp;nbsp;remotos&lt;br /&gt;- Una configuración para todos los nodos (ahora, cada nodo es configurado separadamente)&lt;/p&gt;
&lt;p&gt;Comencé un experimento con un proceso más abstracto de mensajes, que quisiera que pudiera implementar casos de uso como:&lt;/p&gt;
&lt;p&gt;- Un simple hello world&lt;br /&gt;- El ejemplo de decrementar enteros&lt;br /&gt;- Web crawler distribuido&lt;br /&gt;- Una especie de Enterprise Service Bus&lt;/p&gt;
&lt;p&gt;Pueden ver mis primeros pasos en:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjProcessor" href="http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjProcessor"&gt;http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjProcessor&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Todavía en desarrollo.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1677100" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjMessages/default.aspx">AjMessages</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Concurrency+and+Coordination+Runtime/default.aspx">Concurrency and Coordination Runtime</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Decentralized+Software+Services/default.aspx">Decentralized Software Services</category></item></channel></rss>