作为自己的客户端的服务

Posted

技术标签:

【中文标题】作为自己的客户端的服务【英文标题】:A service acting as client of its own 【发布时间】:2016-09-25 18:55:58 【问题描述】:

考虑这种情况:

    WCF 服务已启动并正在运行。 服务需要每隔一段时间调用一次。

我现在所做的是添加对同一服务的服务引用,并在服务配置文件中添加了一个额外的端点 + 客户端。在 net.tcp 上工作。

它工作正常,但我在某处读到您可以使用“进程中”托管来连接到服务而不使用代理。这样您就可以摆脱配置并拥有更简洁的代码。

因此,不要使用附带的配置设置:

DeliveryOwnClient.DeliveryClient deliveryObject = new DeliveryOwnClient.DeliveryClient("netTcpDeliveryService");

我想在没有任何配置的情况下使用它:

IDelivery deliveryObject = InProcessFactory.CreateInstance<DeliveryService.Delivery, IDelivery>();

但这会引发异常“http://localhost:8003/DeliveryService 的 ChannelDispatcher 与合同“IMetadataExchange”无法打开 IChannelListener。Uri net.tcp://localhost:9003/DeliveryService 的注册已经存在”

CreateInstance 的实现如下所示:

ServiceHost host = new ServiceHost(typeof(S));
string address = "net.pipe://" + Environment.MachineName + "/" + Guid.NewGuid();

host.AddServiceEndpoint(typeof(I), Binding, address);
host.Open();

所以我添加了一个 net.pipe 基地址,但它失败了,因为已经有东西在 net.tcp 上运行。

** 编辑 **

至少弄清楚为什么会发生这种情况。

该服务在 app.config 中配置了两个基地址

<service name="DeliveryService.Delivery">
     <endpoint binding="netTcpBinding" contract="DeliveryService.IDelivery"/>
     <host>
       <baseAddresses>
         <add baseAddress="http://localhost:8003/DeliveryService" />
         <add baseAddress="net.tcp://localhost:9003/DeliveryService" />
       </baseAddresses>
     </host>   
</service>

宿主构建时

ServiceHost host = new ServiceHost(typeof(S));                

它会在配置文件中找到该部分并自动添加 net.tcp 和 http 基地址。 我添加了 net.pipe,但这没关系。打开服务后发现 net.tcp 已经在运行,所以不会继续运行。

所以我想我的问题变成了:是否可以在不读取 app.config 的情况下构造 ServiceHost?

【问题讨论】:

【参考方案1】:

Jay 设法弄明白了! ServiceHost 派生自 ServiceHostBase,该类有一个名为 ApplyConfiguration 的虚函数。所以我创建了一个派生自 ServiceHost 并覆盖 ApplyConfiguration 的类......并将其留空。

class ServiceHostNoConfig<S> : ServiceHost where S : class

    public ServiceHostNoConfig(string address)
    
        UriSchemeKeyedCollection c = new UriSchemeKeyedCollection(new Uri(address));
        InitializeDescription(typeof(S), c);
    

    public new void InitializeDescription(Type serviceType, UriSchemeKeyedCollection baseAddresses)
    
        base.InitializeDescription(serviceType, baseAddresses);
    

    protected override void ApplyConfiguration()
    
    

像这样使用它:

        ServiceHost host = new ServiceHostNoConfig<S>(address);

        host.AddServiceEndpoint(typeof(I), Binding, address);

【讨论】:

以上是关于作为自己的客户端的服务的主要内容,如果未能解决你的问题,请参考以下文章

时间同步ntp服务的安装与配置(作为客户端的配置

CA证书 & https通信

从Android访问Windows WebService获取IP地址

iOS底层面试题(下篇)

XMPP:使客户端仅对该客户端的其他实例在线显示

简单的单进程FTP服务器的实现