【问题标题】:Different services on different ports in WCFWCF中不同端口上的不同服务
【发布时间】:2016-05-12 18:58:03
【问题描述】:

我想使用 WCF 公开两个不同的接口:

  • 内部(IPC 通信)
  • 外部(Http REST)

外部接口不应该能够看到或使用内部接口,所以我想的是在不同的端口上托管这两个服务,例如(内部为 8000,外部为 8001)然后阻塞 8000 端口上的所有外部通信。

此外,我尝试使用命名管道进行 IPC 通信,但遇到了问题。如果发生意外情况,即服务崩溃或离线,客户端也必须重新启动才能通过命名管道与服务建立通信。这是正常行为吗?可以避免吗?

到目前为止,我有以下代码:

// Service Host
var host = new ServiceHost(serviceContract, new Uri(_address));
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
var behaviour = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
behaviour.InstanceContextMode = InstanceContextMode.Single;

// Local Endpoint
host.AddServiceEndpoint(typeof(ILocalServiceContract), new BasicHttpBinding(), "Local");
host.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

// External Endpoint
var webHttpBidning = new WebHttpBinding { TransferMode = TransferMode.Streamed };
var externalEndPoint = host.AddServiceEndpoint(typeof(IExternalServiceContract), webHttpBidning, "External");
externalEndPoint.Behaviors.Add(new WebHttpBehavior());

它们目前都托管在我想避免的同一个端口上,我对 WCF 还很陌生,我真的可以使用一些指导来获得最佳实践以及我做错了什么。如前所述,如果我的问题可以解决,“BasicHttpBinding”可能会替换为命名管道。

期待听到专家的意见,如果您需要任何澄清,请随时询问:)

【问题讨论】:

  • that the service crashes or goes offline the client would also have to be restarted to be able to establish the communication with the service via the named pipes. 这意味着您没有正确处理故障。您需要销毁代理并创建一个新代理以重新建立连接。这就是为什么重新启动客户端可以解决它,因为它是代理的新实例。一旦代理出现故障,就再也不能使用了。
  • 感谢您的回答。如果我通过 MEX 公开命名管道绑定,我如何销毁代理并且每次都必须这样做?一个代码示例或链接会非常好:)
  • github.com/rmandvikar/WcfServiceClientHelper 非常适合为您管理代理实例化
  • 对于别人的评论,强类型WCF配置绝对是正确的选择。这是 Juval Lowy 打算使用它的唯一方式。微软无缘无故地强加了 xml,只是因为在过去的几年里 xml config is the bees kneeseverything 需要 moar xml。 关于 WCF 的一切都是假设的是约定优于配置,但你永远不会知道微软如何在其上构建对话框,这完全是讽刺。

标签: c# wcf wcf-data-services wcf-binding


【解决方案1】:

我在服务器上使用以下代码解决了这个问题。在通过命名管道与服务器通信的客户端上,我使用“WcfClientProxyGenerator”库来生成容错客户端代理。

_namedPipeAddress = "net.pipe://localhost/";
_httpAddress = "http://localhost:8000";

var host = new ServiceHost(serviceContract, new Uri(_namedPipeAddress), new Uri(_httpAddress));

host.Description.Behaviors.Add(new ServiceMetadataBehavior { });

var behaviour = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
behaviour.InstanceContextMode = InstanceContextMode.Single;
behaviour.IncludeExceptionDetailInFaults = true;

// Local Endpoint
host.AddServiceEndpoint(typeof(ILocalServiceContract), new NetNamedPipeBinding(), "Local");
host.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexNamedPipeBinding(), "mex");

//// External Endpoint
var webHttpBidning = new WebHttpBinding { TransferMode = TransferMode.Streamed };
var externalEndPoint = host.AddServiceEndpoint(typeof(IExternalServiceContract), webHttpBidning, new Uri(_httpAddress));
externalEndPoint.Behaviors.Add(new WebHttpBehavior());

有关此解决方案的进一步改进,请随时发表评论:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    相关资源
    最近更新 更多