我有一个无状态服务,我正在将一些CloudService WCF端点迁移到。这些点是公开的,需要我能够通过引用>使用 WS-MetadataExchange 来发现它们的属性。从Visual Studio项目以及 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 以及引用&gt;添加服务参考可以使用 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-MSFT (下方)的建议,我现在首先创建通信监听器:
var testCommunicationListener = new WcfCommunicationListener<ITestContract>(
this.Context,
new TestService(),
WcfUtility.CreateTcpClientBinding(),
"WcfServiceEndpoint"
);
然后修改 ServiceHost 对象以允许 MetadataExchange 行为:
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)};
当我将其推送到本地群集时,我收到以下错误:
服务包含多个具有不同ContractDescriptions的ServiceEndpoints,每个ServiceDesndpoints都具有Name =&#39; ITestContract&#39;和命名空间=&#39; http://tempuri.org/&#39;。 为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"));
这给了我以下错误:
Replica在API调用中有多个失败:IStatelessServiceInstance.Open();错误= System.NullReferenceException(-2147467261) 你调用的对象是空的。 在Microsoft.ServiceFabric.Services.Communication.Wcf.Runtime.WcfCommunicationListener
1.b__0(IAsyncResult ar) at System.Threading.Tasks.TaskFactory
1.FromAsyncCoreLogic(IAsyncResult) iar,Func2 endFunction, Action
1 endAction,Task`1 promise,Boolean requiresSynchronization)
我尝试了其他一些类似结果的变体......
我还尝试在默认绑定上允许MetadataExchange行为(不创建任何其他端点)。但在这种情况下,我如何知道我的端点网址是什么?我尝试使用 net.tcp:// localhost:8081 / TestService ( 应该 是默认设置),但我无法连接到控制台应用程序或WcfTestClient。
更新2
我可以根据需要托管我的WCF端点,只需将MetadataExchangeBinding作为附加端点添加,并在其中分配我想要的服务路径:
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"));
答案 0 :(得分:1)
您可以通过访问主机属性在打开通信侦听器之前自定义ServiceHost。
默认情况下,代码会添加一些行为,包括服务调试和限制行为,因此如果删除SDK中提供的WCF的客户端堆栈可能无法正常运行。