首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用用于外部客户端和WcfTestClient的WcfTestClient从Service公开WCF/TCP端点

使用用于外部客户端和WcfTestClient的WcfTestClient从Service公开WCF/TCP端点
EN

Stack Overflow用户
提问于 2017-03-14 19:42:52
回答 1查看 849关注 0票数 1

我有一个无状态服务,我正在将一些CloudService WCF迁移到它。这些端点是可公开使用的,并要求我能够使用WS-MetadataExchange通过Visual项目和WCFTestClient.的两个引用>添加服务引用来发现它们的属性

我遵循了一些教程,并设置了一个测试端点:

代码语言:javascript
复制
 <Endpoint Protocol="tcp" Name="WcfServiceEndpoint" Type="Input" Port="8081" />

以及服务合同

代码语言:javascript
复制
[ServiceContract]
public interface ITestContract
{
    [OperationContract]
    int TestMethod(int value1, int value2);
}

方法:

代码语言:javascript
复制
public class TestService : ITestContract
{
    public int TestMethod(int value1, int value2)
    {
        var result = value1 + value2;
        return result;
    }
}

以及服务侦听器覆盖:

代码语言:javascript
复制
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {

return new[] { new ServiceInstanceListener((context) =>
    new WcfCommunicationListener<ITestContract>(
        this.Context,
        new TestService(),
        WcfUtility.CreateTcpClientBinding(),
        "WcfServiceEndpoint"
    )
)};

在我的上一个项目(我正在迁移)中,我设置了自定义的ServiceHost对象,并能够自定义它们的绑定/Urls。我能让客户发现这些服务很好。我需要能够以相同的方式公开这个服务,以便WcfTestClient以及引用> Add 可以使用WS-MetadataExchange.发现它们的属性现在,我甚至无法控制服务路径是什么!

理想情况下,我希望仍然使用ServiceHost

代码语言:javascript
复制
var host = new ServiceHost(ITestContract);
host.AddServiceEndpoint(TestService, new NetTcpBinding(SecurityMode.None), "net.tcp://...", new Uri("net.tcp://..."));
host.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
host.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });
host.Open();

更新

根据VipulM(以下)的建议,我现在首先创建通信侦听器:

代码语言:javascript
复制
var testCommunicationListener = new WcfCommunicationListener<ITestContract>(
    this.Context,
    new TestService(),
    WcfUtility.CreateTcpClientBinding(),
    "WcfServiceEndpoint"
);

然后修改ServiceHost对象以允许行为:

代码语言:javascript
复制
ServiceMetadataBehavior metaDataBehavior = new ServiceMetadataBehavior();
testCommunicationListener.ServiceHost.Description.Behaviors.Add(metaDataBehavior);

除了允许错误中的异常细节之外,还允许:

代码语言:javascript
复制
testCommunicationListener.ServiceHost.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
testCommunicationListener.ServiceHost.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });

然后创建一个服务端点(使用我想要的服务路径):

代码语言:javascript
复制
testCommunicationListener.ServiceHost.AddServiceEndpoint(typeof(ITestContract), new NetTcpBinding(SecurityMode.None), "net.tcp://localhost:8081/Services/Tests", new Uri("net.tcp://localhost:8081/Services/Tests"));

以及MexEndpoint (允许在TCP上绑定MetaExchange ):

代码语言:javascript
复制
Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
testCommunicationListener.ServiceHost.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "net.tcp://localhost:8081/Services/Tests/mex", new Uri("net.tcp://localhost:8081/Services/Tests/mex"));

最后,我将侦听器分配给无状态服务:

代码语言:javascript
复制
return new[] { new ServiceInstanceListener((context) => testCommunicationListener)};

当我将它推到本地集群时,会得到以下错误:

该服务包含多个具有不同ServiceEndpoints的ContractDescriptions,每个ContractDescriptions都有名称=‘ITestContract’和Namespace='http://tempuri.org/‘。要么为ContractDescriptions提供唯一的名称和名称空间,要么确保ServiceEndpoints具有相同的ContractDescription实例。

我想也许我需要删除默认端点以避免这种冲突,所以我尝试了:

代码语言:javascript
复制
 testCommunicationListener.ServiceHost.Description.Endpoints.RemoveAt(0);

打电话之前:

代码语言:javascript
复制
testCommunicationListener.ServiceHost.AddServiceEndpoint(typeof(ITestContract), new NetTcpBinding(SecurityMode.None), "net.tcp://localhost:8081/Services/Tests", new Uri("net.tcp://localhost:8081/Services/Tests"));
Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
testCommunicationListener.ServiceHost.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "net.tcp://localhost:8081/Services/Tests/mex", new Uri("net.tcp://localhost:8081/Services/Tests/mex"));

这给了我以下错误:

副本在API调用中有多个失败: IStatelessServiceInstance.Open();Error = System.NullReferenceException (-2147467261)对象引用没有设置为对象的实例。在Microsoft.ServiceFabric.Services.Communication.Wcf.Runtime.WcfCommunicationListener1.b__0(IAsyncResult ar) at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar,Func2 endFunction, Action1 endAction,iar‘1 promise,Boolean )

我尝试过一些类似结果的变体.

我还尝试允许默认绑定上的MetadataExchange行为(而不创建任何附加端点)。但是在这种情况下,我如何知道我的端点url是什么?我试过使用net.tcp://localhost:8081/TestService (应该是默认的),但是我不能通过控制台应用程序或WcfTestClient连接到它。

更新2

我只需将MetadataExchangeBinding添加为附加端点,并在以下内容中分配所需的服务路径,就可以按需要托管WCF端点:

代码语言:javascript
复制
Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
testCommunicationListener.ServiceHost.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "net.tcp://localhost:8081/Services/Tests/mex", new Uri("net.tcp://localhost:8081/Services/Tests/mex"));
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-15 07:23:53

您可以通过访问主机属性来自定义通信侦听器打开之前的ServiceHost。

ServiceHost

默认情况下,代码添加的行为很少,包括服务调试和节流行为,因此如果删除SDK中提供的WCF客户端堆栈可能无法正常工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42795147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档