我有一个无状态服务,我正在将一些CloudService WCF迁移到它。这些端点是可公开使用的,并要求我能够使用WS-MetadataExchange通过Visual项目和WCFTestClient.的两个引用>添加服务引用来发现它们的属性
我遵循了一些教程,并设置了一个测试端点:
<Endpoint Protocol="tcp" Name="WcfServiceEndpoint" Type="Input" Port="8081" />以及服务合同
[ServiceContract]
public interface ITestContract
{
[OperationContract]
int TestMethod(int value1, int value2);
}方法:
public class TestService : ITestContract
{
public int TestMethod(int value1, int value2)
{
var result = value1 + value2;
return result;
}
}以及服务侦听器覆盖:
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
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(以下)的建议,我现在首先创建通信侦听器:
var testCommunicationListener = new WcfCommunicationListener<ITestContract>(
this.Context,
new TestService(),
WcfUtility.CreateTcpClientBinding(),
"WcfServiceEndpoint"
);然后修改ServiceHost对象以允许行为:
ServiceMetadataBehavior metaDataBehavior = new ServiceMetadataBehavior();
testCommunicationListener.ServiceHost.Description.Behaviors.Add(metaDataBehavior);除了允许错误中的异常细节之外,还允许:
testCommunicationListener.ServiceHost.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
testCommunicationListener.ServiceHost.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });然后创建一个服务端点(使用我想要的服务路径):
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 ):
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"));最后,我将侦听器分配给无状态服务:
return new[] { new ServiceInstanceListener((context) => testCommunicationListener)};当我将它推到本地集群时,会得到以下错误:
该服务包含多个具有不同ServiceEndpoints的ContractDescriptions,每个ContractDescriptions都有名称=‘ITestContract’和Namespace='http://tempuri.org/‘。要么为ContractDescriptions提供唯一的名称和名称空间,要么确保ServiceEndpoints具有相同的ContractDescription实例。
我想也许我需要删除默认端点以避免这种冲突,所以我尝试了:
testCommunicationListener.ServiceHost.Description.Endpoints.RemoveAt(0);打电话之前:
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.WcfCommunicationListener
1.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端点:
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"));发布于 2017-03-15 07:23:53
您可以通过访问主机属性来自定义通信侦听器打开之前的ServiceHost。
默认情况下,代码添加的行为很少,包括服务调试和节流行为,因此如果删除SDK中提供的WCF客户端堆栈可能无法正常工作。
https://stackoverflow.com/questions/42795147
复制相似问题