简体   繁体   English

在运行时动态更新 WCF 路由服务配置

[英]Dynamically update WCF Routing Service configuration at runtime

I have been following the WCF Routing Service tutorials on MSDN:我一直在关注 MSDN 上的 WCF 路由服务教程:

Dynamic Configuration 动态配置
Source (See code below) 来源(见下面的代码)

After much pain trying to convert the console examples to IIS hosted prototypes, I now have a WCF Routing Service which updates its configuration once every 5 seconds as per the tutorial.在尝试将控制台示例转换为 IIS 托管原型非常痛苦之后,我现在有一个 WCF 路由服务,它按照教程每 5 秒更新一次其配置。

I now need to trigger this update from a Web page instead of the timer auto updating every 5 seconds but cannot find any examples of how to do this.我现在需要从网页触发此更新,而不是每 5 秒自动更新一次计时器,但找不到有关如何执行此操作的任何示例。 Something like an admin screen which handles CRUD ops for endpoints stored in a DB.类似于管理屏幕的东西,它处理存储在数据库中的端点的 CRUD 操作。 If a user makes a change to the config, the Routing Service will need to update its configuration dynamically.如果用户对配置进行了更改,路由服务将需要动态更新其配置。

Apparently you can do something like this with UDP Announcements and Discovery Services, but I don't want that A simple endpoint which triggers the update called from another app will suffice.显然,您可以使用 UDP 公告和发现服务执行类似的操作,但我不希望触发从另一个应用程序调用的更新的简单端点就足够了。

How do I get a reference to the routing service UpdateBehavior in order to manually call the UpdateRules method?如何获取对路由服务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();
        }
    }    
}

Starting from your ServiceHost instance it's pretty easy:从您的ServiceHost实例开始,这很容易:

var updateBahvaior = serviceHost.Description.Behaviors.Find<UpdateBehavior>();

Then, if you expose a method that calls UpdateRules method from the inner private class, you can call it.然后,如果您公开一个从内部私有类调用UpdateRules方法的方法,则可以调用它。

您可能必须在自定义类中使用公共静态变量...

Found this document online.在网上找到了这个文档。 https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/routing-introduction#dynamic-configuration https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/routing-introduction#dynamic-configuration

RoutingExtension ApplyConfiguration would help here. RoutingExtension ApplyConfiguration 在这里会有所帮助。

Attaching snippet.附上片段。 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM