Динамическое обновление конфигурации службы маршрутизации WCF во время выполнения
Я следовал учебным курсам службы маршрутизации WCF на MSDN:
Динамическая Конфигурация
Источник (см код ниже)
После долгих попыток преобразовать примеры консоли в размещенные на IIS прототипы у меня теперь есть служба маршрутизации WCF, которая обновляет свою конфигурацию каждые 5 секунд, как показано в руководстве.
Теперь мне нужно запустить это обновление с веб-страницы вместо автоматического обновления таймера каждые 5 секунд, но я не могу найти никаких примеров того, как это сделать. Что-то вроде экрана администратора, который обрабатывает операции CRUD для конечных точек, хранящихся в БД. Если пользователь вносит изменения в конфигурацию, службе маршрутизации необходимо будет динамически обновлять свою конфигурацию.
Очевидно, что вы можете сделать что-то подобное с UDP Announcements и Discovery Services, но я не хочу, чтобы простой конечной точки, запускающей обновление, вызываемое из другого приложения, было бы достаточно.
Как получить ссылку на службу маршрутизации UpdateBehavior
для того, чтобы вручную вызвать UpdateRules
метод?
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Routing;
using System.Threading;
namespace ErpRoutingService
{
public class UpdateBehavior : BehaviorExtensionElement, IServiceBehavior
{
void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
RulesUpdateExtension rulesUpdateExtension = new RulesUpdateExtension();
serviceHostBase.Extensions.Add(rulesUpdateExtension);
}
void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
class RulesUpdateExtension : IExtension<ServiceHostBase>, IDisposable
{
bool primary = false;
ServiceHostBase owner;
Timer timer;
void IExtension<ServiceHostBase>.Attach(ServiceHostBase owner)
{
this.owner = owner;
//Call immediately, then every 5 seconds after that.
this.timer = new Timer(this.UpdateRules, this, TimeSpan.Zero, TimeSpan.FromSeconds(5));
}
void IExtension<ServiceHostBase>.Detach(ServiceHostBase owner)
{
this.Dispose();
}
public void Dispose()
{
if (this.timer != null)
{
this.timer.Dispose();
this.timer = null;
}
}
void UpdateRules(object state)
{
//Updating Routing Configuration
RoutingConfiguration rc = new RoutingConfiguration();
var inspector = new ErpMessageInspectorBehavior();
if (this.primary)
{
ServiceEndpoint endPoint101 = new ServiceEndpoint(
ContractDescription.GetContract(typeof(IRequestReplyRouter)),
new BasicHttpBinding(),
new EndpointAddress("http://meldev:62395/ErpIntegrationService.svc"));
endPoint101.EndpointBehaviors.Add(inspector);
rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { endPoint101 });
}
else
{
ServiceEndpoint endPoint102 = new ServiceEndpoint(
ContractDescription.GetContract(typeof(IRequestReplyRouter)),
new BasicHttpBinding(),
new EndpointAddress("http://meldev:62396/ErpIntegrationService.svc"));
endPoint102.EndpointBehaviors.Add(inspector);
rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { endPoint102 });
}
this.owner.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc);
this.primary = !this.primary;
}
}
public override Type BehaviorType
{
get { return typeof(UpdateBehavior); }
}
protected override object CreateBehavior()
{
return new UpdateBehavior();
}
}
}
2 ответа
Начиная с вашего ServiceHost
Например, это довольно просто:
var updateBahvaior = serviceHost.Description.Behaviors.Find<UpdateBehavior>();
Затем, если вы выставите метод, который вызывает UpdateRules
метод из внутреннего частного класса, вы можете вызвать его.
Возможно, вам придется использовать открытые статические переменные в вашем пользовательском классе...
Нашел этот документ в Интернете. https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/routing-introduction
Здесь может помочь RoutingExtension ApplyConfiguration.