Compartilhar via


Este artigo foi traduzido por máquina.

Fundamentos

Roteadores no barramento de serviço

JUVAL LOWY

Minhas duas colunas anteriores, descrevi o problema principal o barramento de serviço .NET foi projetado para resolver — que de conectividade com a Internet e questões relacionadas à segurança. No entanto, o barramento de serviço oferece conectividade muito mais simples e retransmissão de mensagens. Esta coluna começa com o registro de serviço e, em seguida, descreve aspectos de roteadores. Eu dedicar minha próxima coluna para filas na nuvem. Em ambas as colunas, descreverei novos padrões de design poderosas, como combinar meu auxiliar, roteadores e filas de classes e ferramentas para simplificar a experiência geral.

O registro de serviços

O barramento de serviço .NET oferece um feed ATOM de serviços de escuta no endereço base da solução ou em qualquer um dos seus sub-URIs. Você pode exibir o feed, navegando para a solução (ou o URI) com um navegador. O feed serve como um registro e um diretório para os serviços e aspectos (como roteadores e filas) na solução.

Por padrão, o serviço não está visível no navegador. Você controlar o serviço de publicação de registro usando a classe de comportamento de ponto de extremidade ServiceRegistrySettings, que é definida da seguinte maneira:

public enum DiscoveryType
{
Public,
Private
}
public class ServiceRegistrySettings : IEndpointBehavior
{
public ServiceRegistrySettings();
public ServiceRegistrySettings(DiscoveryType discoveryType);
public DiscoveryType DiscoveryMode
{get;set;}
public string DisplayName
{get;set;}
}

O host precisa adicionar esse comportamento por meio de programação para cada ponto de extremidade que deseja publicar no registro. (Não há nenhum comportamento configurável correspondente.) Por exemplo, para publicar todos os pontos de extremidade para o registro, você usaria o código mostrado aqui:

IEndpointBehavior registeryBehavior =
new ServiceRegistrySettings(DiscoveryType.Public);
ServiceHost host = new ServiceHost(typeof(MyService));
foreach(ServiceEndpoint endpoint in host.Description.Endpoints)
{
endpoint.Behaviors.Add(registeryBehavior);
}
host.Open();


Figura 1 A do Explorer de barramento de serviços

Para ajudar a visualizar o barramento de serviço, desenvolvi Service Bus Explorer, mostrado na do Figura 1. A ferramenta aceita o nome da solução para explorar e, depois de fazer logon a alimentação, irá visualizar para você os serviços em execução. Tudo faz o explorer é analisar o feed ATOM e colocar os itens na árvore de para a esquerda. Você pode explorar várias soluções e ver suas páginas de administração de solução no painel à direita. A ferramenta também mostra os roteadores disponíveis e filas e é muito útil na administração-los.

Nuvem como interceptador

O barramento de serviço, de fato, inicialmente foi desenvolvido para abordar os problemas agudo conectividade de chamadas através da Web. No entanto, ele possui o potencial de muito mais. Compare a arquitetura básica do Windows Communication Foundation (WCF) com a arquitetura de barramento de serviço. Em ambos os casos, o cliente não interage diretamente com o serviço, mas em vez disso, as chamadas são interceptadas pelo middleware. No caso do WCF normal, a middleware é o proxy e a cadeia de interpretação leva para o serviço, conforme mostrado no do Figura 2.

No caso das chamadas retransmitidas a middleware consiste a middleware regular do WCF e o barramento de serviço propriamente dito, conforme mostrado no do Figura 3. Do ponto de vista arquitetura, este é o mesmo design — interceptar as chamadas para fornecer valor adicional. Na versão atual do barramento de serviço, esse valor adicional é a capacidade para instalar os roteadores e filas. Na verdade, acho o barramento de serviço tem grande potencial para interceptadores eficientes e sem dúvida aspectos adicionais serão disponibilizados com o tempo.


A Figura 2 do interceptando regular WCF chamadas


Figura 3 A nuvem como interceptador

Junções como roteadores

O barramento de serviço, cada URI na solução é realmente uma junção mensagens endereçável. O cliente pode enviar uma mensagem para a junção, e a junção pode retransmitir para os serviços. No entanto, cada junção também poderá funcionar como um roteador. Vários serviços podem inscrever-se a esse roteador e o roteador pode encaminhar a mensagem cliente mesmo a todos eles ou apenas um único deles, conforme mostrado no do Figura 4.

O cliente é dissociado do serviços por trás do roteador, e quanto o cliente estiver preocupado, pode não ainda haver quaisquer serviços por trás do roteador. Tudo o que o cliente precisa saber é onde o roteador que ele precisa para enviar mensagens para está localizado. Ele confia o roteador para ser configurado com a diretiva de distribuição apropriados. Devido a esse indirectness, as mensagens são inerentemente uma forma e, na verdade, o WCF insiste que a vinculação usada pelo cliente e os serviços de inscrição é a ligação de retransmissão unidirecional. O cliente não tem meios de receber os resultados dos serviços ou de sendo informados sobre sobre de erros do lado do serviço. Esse seria o caso mesmo se a ligação não unidirecional. Se a mensagem de cliente é sendo multiplexada para vários serviços, em seguida, por definição não é nenhum significado para resultados retornados da operação (do qual o serviço?) ou para erros (do qual o serviço?). Também não há nenhuma maneira para os serviços para retorno de chamada para seus clientes.


Figura 4 O barramento de serviços como um roteador

Diretiva de roteador

O administrador de solução gerencia os roteadores independentemente dos serviços. Cada roteador deve ter uma diretiva que regem o comportamento e tempo de vida. Fora da caixa, o administrador de solução deve executar chamadas através de programação para criar e gerenciar roteadores. Todas as diretivas de junção mensagens derivam da classe abstrata JunctionPolicy, mostrada na do Figura 5.

A propriedade de junção detectabilidade é um enum do tipo DiscoverabilityPolicy. Ele controla se a junção está incluída no ATOM feed da solução. Padrões de descoberta para DiscoverabilityPolicy.Managers, que significa que uma diretiva particular. Defini-la como DiscoverabilityPolicy.Public publica o feed. A propriedade ExpirationInstant controla o tempo de vida da junção. Depois que a diretiva tenha expirado, a junção é removida. ExpirationInstant padrão é um dia. Obviamente, que pode ou não ser adequado para seus roteadores (ou filas), portanto, você normalmente precisa definida-lo com o valor desejado e monitorar a ele. Como a junção está prestes a expirar, você deve renovar-se a junção ainda está em uso. Chamo esse o “ tempo de concessão ” da junção de renovação, e chamar a parte que se estende a concessão “ patrocinador ”. Finalmente, a propriedade TransportProtection controla a segurança de transferência de mensagem para a junção. Quando lançamento ou recuperar mensagens do WCF brutas para ou de junções mensagens, você está restrito a usar segurança de transporte com o valor da TransportProtectionPolicy.AllPaths. Segurança de transporte é o padrão para todas as diretivas de junção, e recomendo nunca defini-la como qualquer outro valor.

Figura 5 A classe JunctionPolicy

public enum DiscoverabilityPolicy
{
Managers,Public //More values
}
public enum TransportProtectionPolicy
{
None,AllPaths
}
[DataContract]
public abstract class JunctionPolicy
{
public JunctionPolicy();
public JunctionPolicy(JunctionPolicy policyToCopy);
public DateTime ExpirationInstant
{get;set;}
public DiscoverabilityPolicy Discoverability
{get;set;}
public TransportProtectionPolicy TransportProtection
{get;set;}
//More members
}

Figura 6 A classe RouterPolicy

public enum MessageDistributionPolicy
{
AllSubscribers,
OneSubscriber
}
[DataContract]
public class RouterPolicy : JunctionPolicy,...
{
public RouterPolicy();
public RouterPolicy(RouterPolicy otherRouterPolicy);
public int MaxSubscribers
{get;set;}
public MessageDistributionPolicy MessageDistribution
{get;set;}
//More members
}

Cada diretiva do roteador é expresso com a classe RouterPolicy, definida no do Figura 6. As duas propriedades principais aqui são MaxSubscribers e MessageDistribution. Como seu nome já diz, MaxSubscribers é o número máximo de assinantes simultâneos permitido para se conectar com o roteador. O valor padrão é 1 e o valor máximo é 50. Depois que o roteador estiver maximizada-out, serviços adicionais tentando inscrever-se obtêm um erro. MessageDistribution é um enum do tipo MessageDistributionPolicy e padrões para MessageDistributionPolicy.OneSubscriber--ou seja, apenas um dos serviços inscritos obtém a mensagem. Defini-la como MessageDistributionPolicy.AllSubscribers envia a mensagem a todos os serviços.

Gerenciando a diretiva de roteador

Você pode usar a classe RouterManagementClient, mostrada aqui, para administrar as diretivas de roteador:

public static class RouterManagementClient
{
public static RouterClient CreateRouter(
TransportClientEndpointBehavior credential,
Uri routerUri,RouterPolicy policy);
public static void DeleteRouter(
TransportClientEndpointBehavior credential,
Uri routerUri);
public static RouterClient GetRouter(
TransportClientEndpointBehavior credential,
Uri routerUri);
public static RouterPolicy GetRouterPolicy(
TransportClientEndpointBehavior credential,
Uri routerUri);
public static DateTime RenewRouter(
TransportClientEndpointBehavior credential,
Uri routerUri,TimeSpan requestedExpiration);
}

RouterManagementClient é uma classe estática, e todos os seus métodos requerem o objeto de credencial (do tipo TransportClientEndpointBehavior, discutido na minha coluna anterior (consulte de msdn.microsoft.com/magazine/dd942847.aspx). O seguinte código demonstra criando uma diretiva e um roteador simples:

Uri routerAddress =
new Uri(@"sb://MySolution.servicebus.windows.net/MyRouter/");
TransportClientEndpointBehavior credential = ...;
RouterPolicy policy = new RouterPolicy();
policy.ExpirationInstant = DateTime.UtcNow + TimeSpan.FromMinutes(5);
policy.MaxSubscribers = 4;
policy.MessageDistribution = MessageDistributionPolicy.AllSubscribers;
RouterManagementClient.CreateRouter(credential,routerAddress,policy);

No exemplo, instanciar um objeto de diretiva de roteador e configure a diretiva para alguns valores, como distribuir a mensagem a todos os serviços de inscrição e limitando o roteador para os assinantes não mais do que quatro. O roteador é configurado para ter uma vida curta de somente cinco minutos. Tudo para instalar o roteador é chamar o método CreateRouter da RouterManagementClient com a diretiva e algumas credenciais válidas.

Como alternativa às chamadas através de programação, você pode usar meu Explorer de barramento de serviços para exibir e modificar roteadores. Você pode criar um novo roteador, especificando seu endereço e várias propriedades de diretiva. Muito da mesma forma, você pode excluir todos os roteadores na solução.

Você também pode examinar e modificar as diretivas de roteadores existentes selecionando-os na árvore de solução e interagir com suas propriedades no painel à direita, conforme mostrado no Figura 7.

Tudo o que o cliente precisa fazer para postar mensagens para um roteador é criar um proxy cujo endereço é o endereço do roteador e chamar o proxy.

Inscrever-se em um roteador

Para um serviço receber mensagens de um roteador, ele deve inscrever-primeiro se o roteador adicionando o host de um ponto de extremidade cujo endereço é endereço ’s roteador. Uma maneira de fazer isso é usando a classe auxiliar RouterClient, definida da seguinte maneira:

public sealed class RouterClient
{
public ServiceEndpoint AddRouterServiceEndpoint<T>(
ServiceHost serviceHost);
//More members
}

Os métodos do RouterManagementClient que criar ou obter um roteador retornam uma instância de RouterClient. Você precisará chamar AddRouterServiceEndpoint < T >método com uma instância do seu host de serviço. Você pode também simplesmente adicionar um ponto de extremidade para o host (por meio de programação ou em um arquivo de configuração) cujo endereço é o endereço do roteador. Eis um exemplo:

<service name = "MyService">
<endpoint
address = "sb://MySolution.servicebus.windows.net/MyRouter/"
binding = "netOnewayRelayBinding"
contract = "..."
/>
</service>


Figura 7 um roteador no Explorer do barramento de serviços


Figura 8 assinando roteador para

Usando roteadores

Os roteadores têm três usa. A primeira é a mesma mensagem para vários serviços de difusão. Caso clássico é, claro, publicando eventos a assinar serviços, tratando o barramento de serviço como um hub de eventos middleware. Como mencionado na minha coluna na edição de abril (consulte de msdn.microsoft.com/magazine/dd569756.aspx), há mais eventos publicação que atende aos olhos, portanto, eu Adiar eventos discussão para o final desta coluna.

O segundo uso para um roteador é como um balanceador de carga entre serviços. Se você configurar a diretiva de roteador para distribuir mensagens para somente um único assinante, o roteador em vigor atua como um balanceador de carga entre os serviços de inscrição. Todos os balanceadores de carga execute algumas algoritmo de decidir qual o serviço irá lidar com a próxima mensagem. Os algoritmos comuns incluem round robin, aleatório, alguns justo placar e enfileiramento. Meu teste indica que o barramento de serviço usa um robin pseudo–round — ou seja, era uma boa round robin alguns 95 % do tempo. Para simplificar a criação de um roteador de balanceamento de carga, minha classe auxiliar ServiceBusHelper oferece um número de métodos sobrecarregados CreateLoadBalancingRouter, mostrado aqui:

public static partial class ServiceBusHelper
{
//Uses CardSpace for credential
public static void CreateLoadBalancingRouter(string balancerAddress);
/* Additional CreateLoadBalancingRouter(...)
with different credentials */
}

CreateLoadBalancingRouter cria um roteador com uma diretiva que distribui as mensagens para um único assinante. Ele também detecta se o roteador existe antes de criá-la e automaticamente renova a concessão do roteador. A implementação de roteador CreateLoadBalancing está incluída no download do código deste artigo.

Todos os métodos públicos CreateLoadBalancingRouter tenham tipos de credenciais diferentes (a implementação, forneço usa CardSpace), construir uma instância de TransportClientEndpointBehavior e chamada interna CreateLoadBalancingRouter sobrecarregado. Que versão sobrecarregada cria uma diretiva de balanceamento de carga também publica o roteador para ATOM feed e chama CreateRouter com a diretiva especificada e credenciais. CreateRouter primeiro usa o método RouterExists para verificar se o roteador já foi criado. Infelizmente, é a única maneira de verificar ver se um erro ocorre quando você tenta obter a diretiva do roteador.

Se o roteador se existir, CreateRouter retorna seu RouterClient correspondente. Se o roteador não existir, CreateRouter primeiro criará um timer para monitorar a expiração da concessão, usando uma expressão lambda como um patrocinador. Como o tempo de concessão atinge seu final, o timer chama a expressão lambda para renovar a concessão. CreateRouter, em seguida, cria o roteador.

Roteadores para roteadores

O uso de terceiro para roteadores é para rotear mensagens para outras junções, como outros roteadores (ou filas). Para inscrever-se um roteador para outro, use o método SubscribeToRouter de RouterClient, mostrado aqui:

public sealed class RouterClient
{
public RouterSubscriptionClient SubscribeToRouter(
RouterClient routerClient,
TimeSpan requestedTimeout);
//More members
}
[Serializable]
public class RouterSubscriptionClient
{
public DateTime Expires {get;}
public DateTime Renew(TimeSpan requestedExpiration,
TransportClientEndpointBehavior credential);
public void Unsubscribe(TransportClientEndpointBehavior credential);
//More members
}

SubscribeToRouter aceita o cliente de roteador do roteador de você deseja se inscrever e retorna uma instância de RouterSubscriptionClient. Os principais usos do RouterSubscriptionClient é cancelar a inscrição e renovar a concessão de inscrição.

Por exemplo, suponha que você tenha um serviço, serviço B e serviço C. Você precisa que cada chamada de cliente sempre vai para um serviço e serviço B ou c de serviço. (Imagine que você precisa carregar saldo serviço B e C de serviço mas também mantenha um registro de todas as chamadas no serviço de registro de vôo A). As diretivas de roteador descritas até agora, de entrega para todos os assinantes ou para um único assinante, são inadequadas. No entanto, você pode satisfazer os requisitos facilmente usando dois roteadores, conforme mostrado no Figura 8.

O cliente envia as mensagens para um roteador com uma diretiva de distribuição a todos os serviços de nível superior. Serviço A assina o roteador de nível superior. Um subrouter com uma diretiva de distribuição de um único assinante inscreve-se também ao roteador de nível superior. Inscrever-se os serviços B e C de serviço em que subrouter. Figura 9 mostra a configuração de roteadores necessários e como assinar subrouter para o roteador superior.

Quando se trata de um serviço de inscrição para um roteador de inscrição, é um detalhe importante sobre a assinatura que difere de inscrição para um roteador de nível superior. O ponto de extremidade de serviço deve indicar que está disposto a receber mensagens de roteador inscritos, mesmo que as mensagens são endereçadas ao roteador de nível superior. Essa indicação é feita, definindo a propriedade URI escuta do ponto de extremidade ao serviço da inscrição, tendo o ponto de extremidade serviço próprio endereço o roteador de nível superior. Usando os endereços de endereços no Figura 9, ambos serviço B e C serviço terá que definir seus pontos de extremidade da seguinte maneira:

<service name = "MyService">
<endpoint listenUri =
"sb://MySolution.servicebus.windows.net/MySubRouter/"
address = "sb://MySolution.servicebus.windows.net/MyTopRouter/"
binding = "netOnewayRelayBinding"
contract = "..."
/>
</service>

Você pode automatizar essa configuração com a seguinte extensão de host de serviço:

public static partial class ServiceBusHelper
{
public static void SubscribeToRouter(this ServiceHost host,
string subRouterAddress)
{
for(int index = 0;
index < host.Description.Endpoints.Count;index++)
{
host.Description.Endpoints[index].ListenUri =
new Uri(subRouterAddress);
}
}
//More members
}

Considerando que um roteador pode se inscrever em vários roteadores, os serviços que inscrever-se o roteador de inscrição devem ser muito atento ao qual endereço--ou seja, qual roteador de nível superior--desejam receber mensagens.

Observe que remover o roteador de nível superior ou encerrar a inscrição corta subrouters das mensagens de cliente. Isso, por sua vez, é um recurso de classificações para administradores de solução, que podem usar esta etapa para desligar serviços com eficiência sem fechar seus hosts.

Figura 9 assinando roteador para

Uri topRouterAddress =
new Uri(@”sb://MySolution.servicebus.windows.net/MyTopRouter/");
Uri subRouterAddress =
new Uri(@”sb://MySolution.servicebus.windows.net/MySubRouter/");
TransportClientEndpointBehavior credential = ...;
RouterPolicy topRouterPolicy = new RouterPolicy();
subRouterPolicy.MaxSubscribers = 20;
topRouterPolicy.MessageDistribution =
MessageDistributionPolicy.AllSubscribers;
RouterClient topRouterClient = RouterManagementClient.CreateRouter(
credential,topRouterAddress,topRouterPolicy);
RouterPolicy subRouterPolicy = new RouterPolicy();
subRouterPolicy.MaxSubscribers = 30;
subRouterPolicy.MessageDistribution =
MessageDistributionPolicy.OneSubscriber;
RouterClient subRouterClient = RouterManagementClient.CreateRouter(
credential,subRouterAddress,subRouterPolicy);
RouterSubscriptionClient subscription = subRouterClient.
SubscribeToRouter(topRouterClient,
TimeSpan.MaxValue);
//Sometime later
subscription.Unsubscribe(credential);

Usando roteadores para eventos

Como mencionei anteriormente, a junção de mensagens no barramento de serviço pode atuar como um hub crua eventos e mensagens para inscrever-se em serviços de difusão. Você precisa instalar uma diretiva de roteador que maximiza o número de assinantes e notifica todos os assinantes. Portanto, as limitações de fazer são semelhantes às usando os eventos de ligação (discutidas na minha coluna de abril às de msdn.microsoft.com/magazine/dd569756.aspx). Não há nenhuma inscrição por operação e, conseqüentemente, os assinantes (todos eles) sempre receber todos os eventos, até mesmo eventos que não faz sobre (aqueles que têm apenas um ponto de extremidade correspondente).

A solução é criar um único roteador para tratar todos os eventos, mas para criar um roteador por evento. Serviços que estejam interessados em apenas esse evento serão inscrever-se determinado roteador esse evento ’s. Como com os eventos de ligação, ter um roteador por evento é conseguido com cada assinante gerenciar uma instância de host por operação, porque um único host que monitora todos os roteadores não fará nada para filtrar os eventos. O assinante precisa abrir e fechar o host respectivo para se inscrever ou cancelar a inscrição para o evento. Isso requer código entediante e repetitivo.

A boa notícia é que a classe auxiliar EventsRelayHost que apresentei na minha coluna anterior já está fazendo isso e com um pouco de refatoração de uma classe base comum denominada EventsHost, pode ser adaptado para uso com roteadores em vez da ligação de retransmissão de eventos. (Para roteadores, você precisa apenas a ligação de retransmissão unidirecional.)

Primeiro, defini a classe base abstrata EventsHost, mostrada aqui:

//Partial listing
public abstract class EventsHost
{
public EventsHost(Type serviceType,string baseAddress);
public EventsHost(Type serviceType,string[] baseAddresses);
public abstract void SetBinding(NetOnewayRelayBinding binding);
public abstract void SetBinding(string bindingConfigName)
protected abstract NetOnewayRelayBinding GetBinding();
public void Subscribe();
public void Subscribe(Type contractType);
public void Subscribe(Type contractType,string operation)
public void Unsubscribe();
public void Unsubscribe(Type contractType);
public void Unsubscribe(Type contractType,string operation);
}

As duas subclasses, EventsRelayHost e EventsRouterHost, são definidas na implementação de .o Figura 10 de EventsHost e EventsRelayHost é apresentado em minha coluna anterior.

Figura 10 definindo EventsRelayHost

//For use with the events binding, see previous column
public class EventsRelayHost : EventsHost
{...}
public class EventsRouterHost : EventsHost
{
public override void SetBinding(NetOnewayRelayBinding binding)
{
RelayBinding = binding;
}
public override void SetBinding(string bindingConfigName)
{
SetBinding(new NetOnewayRelayBinding(bindingConfigName));
}
protected override NetOnewayRelayBinding GetBinding()
{
return RelayBinding ?? new NetOnewayRelayBinding();
}
}

EventsRouterHost é semelhante a EventsRelayHost--ambos gerenciar um host por evento, e é importante não se o endereço que elas monitoram for o endereço de um ponto de extremidade eventos ou que um roteador. A única diferença é que o EventsRouterHost deve usar a retransmissão unidirecional ligação a receber os eventos, em oposição aos eventos de ligação usados por EventsRelayHost. Diferente, EventsRouterHost e EventsRelayHost devem ser idênticos. Isso é refletido no fato de que ambos derivam EventsHost, que faz o trabalho pesado de gerenciar os hosts. Tanto EventsRouterHost EventsRelayHost simplesmente substituem os métodos de gerenciamento de ligação.

Diferente, usar EventsRouterHost é exatamente como usando EventsRelayHost, onde inscrever e Cancelar inscrição funcionam em vez de abrir e fechar o host:

EventsHost host = new EventsRouterHost(typeof(MyService),
"sb://MySolution.servicebus.windows.net/...");
host.Subscribe();
...
host.Unsubscribe(typeof(IMyEvents),"OnEvent2");

O código anterior abre e fecha um host respectivo internamente que monitora apenas esse evento.

Criando eventos roteadores

EventsRouterHost requer o administrador de solução para configurar os roteadores com antecedência e ele não tentará criar os roteadores. Fiz essa opção deliberadamente para separar configurando os roteadores e suas diretivas de assinantes. Todos os o cliente vê é endereço ’s a junção e para acionar um evento sobre uma ligação de retransmissão unidirecional, você pode usar o mesmo EventRelayClientBase apresentada na minha coluna anterior para publicar os eventos.

Para simplificar o esforço de criar os roteadores de evento, você pode usar meu ServiceBusHelper para criar os roteadores:

public static partial class ServiceBusHelper
{
//Uses CardSpace for credential
public static RouterClient[] CreateEventRouters(string baseAddress,
Type contractType);
/* Additional CreateEventRouters(...) with different credentials */
}

CreateEventRouters aceita o endereço base do roteador. Ele acrescenta ao endereço base, o nome do contrato e o nome da operação e abre um roteador individual nesse endereço. Por exemplo, receber o seguinte endereço base:

sb://MySolution.servicebus.windows.net/

e essa definição de contrato:

[ServiceContract]
interface IMyEvents
{
[OperationContract(IsOneWay = true)]
void OnEvent1();
[OperationContract(IsOneWay = true)]
void OnEvent2(int number);
[OperationContract(IsOneWay = true)]
void OnEvent3(int number,string text);
}

CreateEventRouters cria os seguintes roteadores:

sb://MySolution.servicebus.windows.net/IMyEvents/OnEvent1/
sb://MySolution.servicebus.windows.net/IMyEvents/OnEvent2/
sb://MySolution.servicebus.windows.net/IMyEvents/OnEvent3/

Isso é exatamente o que espera EventsRouterHost. Download do código deste artigo fornece uma listagem parcial da implementação de ServiceBusHelper.CreateEventRouters, sem tratamento de erros e alguns dos métodos de segurança sobrecarregado.

O CreateEventRouters pública que não leva nenhum padrão de credenciais a usar o CardSpace criando um objeto TransportClientEndpointBehavior e passá-la para o método interno. Esse método usa a reflexão para obter a coleção de operações no tipo de contrato de serviço. Para cada operação, ele chama o método CreateEventRouter, passando-o endereço para o roteador e a diretiva. A diretiva para cada roteador maxes o número de assinantes, entrega os eventos para todos eles e publica o roteador para ATOM feed.

Roteadores vs. os eventos de ligação

Para inscrever-se a maioria dos casos de cloud-based, publicar-em soluções, recomendo os eventos de ligação. Primeiro, acho o limite do número máximo de assinantes para ser um handicap sério. É possível que 50 será mais adequado para seu aplicativo. No entanto, se tempo você precisa oferecem suporte a assinantes mais? Não esse limite é imposto em eventos de ligação. Outros problemas com a abordagem de roteadores são a necessidade para criar os roteadores com antecedência e se preocupar com patrocínio de concessão. Os eventos de ligação, por outro lado, funciona como um roteador crua ad-hoc sem esses passivos.

Há dois graces salvar para gerenciamento de eventos com o roteador. A primeira é a opção para os administradores de sistema para usar ferramentas como o Gerenciador de barramento de serviços para gerenciar os assinantes, até mesmo indiretamente por gerenciar os roteadores. A segunda e mais ubstantial, é a capacidade para combinar roteadores com filas para criar editores na fila e filas de assinantes, a abordagem descreverei na minha próxima coluna.

Juval Lowy é arquiteto de software na IDesign e fornece treinamento em WCF e consultoria de arquitetura WCF. Seu livro recente é “ Programming WCF Services, 2ª Edição ” (O’Reilly, 2008). Ele também é o diretor regional da Microsoft do Vale do Silício. Entre em contato com Juval em de idesign.net.