同一端口上的无状态 WCF 服务侦听器
Stateless WCF service listener on same port
我们有这样一种情况,我们一直在使用基于 WCF 的普通 windows 服务,我们在同一地址上托管多个侦听器,端口仅在地址上添加额外的后缀,例如:
http://localhost:9000/<listener1_name>/
http://localhost:9000/<listener2_name>/
http://localhost:9000/<listener3_name>/
http://localhost:9000/<listener4_name>/
但是,既然我们喜欢通过使用服务结构转移到 asuze,我们就喜欢一步一步来。
其中一个步骤是将此 windows 服务移动到 Service Fabric 环境中...
正如您可能意识到的那样,我没有做的是设置多个侦听相同端口但具有不同后缀的无状态服务。
我认为 EndPoint
中的 PathSuffix
属性可以解决问题,但我只获得了其中一项服务 运行。其他的写的很清楚,端口已经被占用了
希望这会奏效:
<Resources>
<Endpoints>
<Endpoint Name="WcfService1Endpoint" Protocol="tcp" Port="9000" PathSuffix="Service1ListenerName" /
<Endpoints>
</Resources>
然后在下一个:
<Resources>
<Endpoints>
<Endpoint Name="WcfService2Endpoint" Protocol="tcp" Port="9000" PathSuffix="Service2ListenerName" />
<Endpoints>
</Resources>
等等等等...
有没有其他方法可以解决我的情况,或者我现在需要更改整个结构?
希望有人解决了这个问题!
谢谢!
好的,我是这样做的:
我建基地class
public class StatelessServiceBase : StatelessService
{
.
.
.
protected ICommunicationListener CreateListener(StatelessServiceContext context, object service, string interfaceName, AuthenticationInspector inspector = null)
{
Uri baseUri = new Uri($"{Util.GetBaseServerAddress()}{service.GetType().Name}");
ServiceHost serviceHost = new ServiceHost(service.GetType(), baseUri);
this.AddServiceEndpoint(serviceHost, service, interfaceName, inspector);
return new ServiceHostCommunicationListener(serviceHost, baseUri.AbsoluteUri);
}
private void AddServiceEndpoint(ServiceHost serviceHost, object service, string interfaceName, AuthenticationInspector inspector)
{
var binding = new WSHttpBinding(SecurityMode.None);
binding.SendTimeout = new TimeSpan(0, 10, 0);
binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
binding.MaxBufferPoolSize = 2147483647;
binding.MaxReceivedMessageSize = 2147483647;
binding.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas
{
MaxDepth = 2147483647,
MaxStringContentLength = 2147483647,
MaxArrayLength = 2147483647,
MaxBytesPerRead = 2147483647,
MaxNameTableCharCount = 2147483647
};
if (inspector == null)
{
serviceHost.AddServiceEndpoint(service.GetType().GetInterface(interfaceName), binding, string.Empty);
}
else
{
serviceHost.AddServiceEndpoint(service.GetType().GetInterface(interfaceName), binding, string.Empty).Behaviors.Add(inspector);
}
}
}
然后我从无状态服务中调用了 CreateListener class:
internal class MyStatelessService : StatelessServiceBase
{
public MyStatelessService(StatelessServiceContext context)
: base(context)
{
}
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
yield return new ServiceInstanceListener(context =>
this.CreateListener(context, new MyService(), "IMyService", new AuthenticationInspector()));
}
}
Settings.xml 看起来像这样:
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Section Name="Configuration">
<Parameter Name="BaseServerAddress" Value="http://localhost:9000/"/>
</Section>
</Settings>
连同reader函数:
public class Util
{
internal static string GetBaseServerAddress()
{
var configurationPackage = FabricRuntime.GetActivationContext().GetConfigurationPackageObject("Config");
var baseServerAddress =
configurationPackage.Settings.Sections["Configuration"].Parameters["BaseServerAddress"];
return baseServerAddress.Value;
}
}
在服务结构中添加多项服务并...工作得很好! :)
我们有这样一种情况,我们一直在使用基于 WCF 的普通 windows 服务,我们在同一地址上托管多个侦听器,端口仅在地址上添加额外的后缀,例如:
http://localhost:9000/<listener1_name>/
http://localhost:9000/<listener2_name>/
http://localhost:9000/<listener3_name>/
http://localhost:9000/<listener4_name>/
但是,既然我们喜欢通过使用服务结构转移到 asuze,我们就喜欢一步一步来。 其中一个步骤是将此 windows 服务移动到 Service Fabric 环境中...
正如您可能意识到的那样,我没有做的是设置多个侦听相同端口但具有不同后缀的无状态服务。
我认为 EndPoint
中的 PathSuffix
属性可以解决问题,但我只获得了其中一项服务 运行。其他的写的很清楚,端口已经被占用了
希望这会奏效:
<Resources>
<Endpoints>
<Endpoint Name="WcfService1Endpoint" Protocol="tcp" Port="9000" PathSuffix="Service1ListenerName" /
<Endpoints>
</Resources>
然后在下一个:
<Resources>
<Endpoints>
<Endpoint Name="WcfService2Endpoint" Protocol="tcp" Port="9000" PathSuffix="Service2ListenerName" />
<Endpoints>
</Resources>
等等等等...
有没有其他方法可以解决我的情况,或者我现在需要更改整个结构?
希望有人解决了这个问题!
谢谢!
好的,我是这样做的:
我建基地class
public class StatelessServiceBase : StatelessService
{
.
.
.
protected ICommunicationListener CreateListener(StatelessServiceContext context, object service, string interfaceName, AuthenticationInspector inspector = null)
{
Uri baseUri = new Uri($"{Util.GetBaseServerAddress()}{service.GetType().Name}");
ServiceHost serviceHost = new ServiceHost(service.GetType(), baseUri);
this.AddServiceEndpoint(serviceHost, service, interfaceName, inspector);
return new ServiceHostCommunicationListener(serviceHost, baseUri.AbsoluteUri);
}
private void AddServiceEndpoint(ServiceHost serviceHost, object service, string interfaceName, AuthenticationInspector inspector)
{
var binding = new WSHttpBinding(SecurityMode.None);
binding.SendTimeout = new TimeSpan(0, 10, 0);
binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
binding.MaxBufferPoolSize = 2147483647;
binding.MaxReceivedMessageSize = 2147483647;
binding.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas
{
MaxDepth = 2147483647,
MaxStringContentLength = 2147483647,
MaxArrayLength = 2147483647,
MaxBytesPerRead = 2147483647,
MaxNameTableCharCount = 2147483647
};
if (inspector == null)
{
serviceHost.AddServiceEndpoint(service.GetType().GetInterface(interfaceName), binding, string.Empty);
}
else
{
serviceHost.AddServiceEndpoint(service.GetType().GetInterface(interfaceName), binding, string.Empty).Behaviors.Add(inspector);
}
}
}
然后我从无状态服务中调用了 CreateListener class:
internal class MyStatelessService : StatelessServiceBase
{
public MyStatelessService(StatelessServiceContext context)
: base(context)
{
}
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
yield return new ServiceInstanceListener(context =>
this.CreateListener(context, new MyService(), "IMyService", new AuthenticationInspector()));
}
}
Settings.xml 看起来像这样:
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Section Name="Configuration">
<Parameter Name="BaseServerAddress" Value="http://localhost:9000/"/>
</Section>
</Settings>
连同reader函数:
public class Util
{
internal static string GetBaseServerAddress()
{
var configurationPackage = FabricRuntime.GetActivationContext().GetConfigurationPackageObject("Config");
var baseServerAddress =
configurationPackage.Settings.Sections["Configuration"].Parameters["BaseServerAddress"];
return baseServerAddress.Value;
}
}
在服务结构中添加多项服务并...工作得很好! :)