gpt4 book ai didi

c# - 使用 net.tcp ://0. 0.0.0 :0/blah announces net. tcp ://0. 0.0.0:0/blah 使用服务主机发现 WCF

转载 作者:行者123 更新时间:2023-11-30 12:10:52 30 4
gpt4 key购买 nike

我想要一个可以监听所有接口(interface)并为每个接口(interface)发布发现公告的可发现服务。我希望最终能够使用 tcp://0.0.0.0:0/blah 作为服务端点在配置文件中配置它。但是当我运行下面的代码时,它发出的公告使用 tcp://0.0.0.0:0/blah 作为对客户端无用的 EndpointAddress。

我想收到来自 tcp://0.0.0.0:0/blah 的每个端点的公告,我更愿意使用配置文件而不是如下所示的程序化服务主机设置。任何解决方法的想法?

    [TestFixtureSetUp]
public void SetUp()
{
service1 = new MyContract();
EndpointDiscoveryBehavior discoveryBehavior = new EndpointDiscoveryBehavior();
ServiceDiscoveryBehavior serviceDiscoveryBehavior = new ServiceDiscoveryBehavior(discoveryUri);
serviceDiscoveryBehavior.AnnouncementEndpoints.Add(new UdpAnnouncementEndpoint(announcementUri));

serviceHost1 = new ServiceHost(service1,
new Uri[] {new Uri("net.pipe://localhost"), new Uri("net.tcp://0.0.0.0:0")});
ServiceEndpoint localEndpoint1 = serviceHost1.AddServiceEndpoint(typeof (IContract),
new NetNamedPipeBinding(),
"/Pipe");
ServiceEndpoint localEndpoint2 = serviceHost1.AddServiceEndpoint(typeof (IContract),
new NetTcpBinding(),
"/Tcp");
localEndpoint2.Behaviors.Add(discoveryBehavior);
serviceHost1.Description.Behaviors.Add(serviceDiscoveryBehavior);
serviceHost1.AddServiceEndpoint(new UdpDiscoveryEndpoint(discoveryUri));

serviceHost1.Open();
}

最佳答案

虽然我的解决方案可能不“正确”,但严格来说(如果您问我,这实际上应该在 WCF 本身中修复),但它有效,并且足以满足我的目的。

首先,声明一个新的端点行为,如下所示:

public class WcfDiscoveryAddressFixEndpointBehavior : IEndpointBehavior, IDispatchMessageInspector
{
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
// Attach ourselves to the MessageInspectors of reply messages
clientRuntime.CallbackDispatchRuntime.MessageInspectors.Add(this);
}

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
object messageProperty;
if (!OperationContext.Current.IncomingMessageProperties.TryGetValue(RemoteEndpointMessageProperty.Name, out messageProperty)) return null;
var remoteEndpointProperty = messageProperty as RemoteEndpointMessageProperty;
if (remoteEndpointProperty == null) return null;

// Extract message body
string messageBody;
using (var oldMessageStream = new MemoryStream())
{
using (var xw = XmlWriter.Create(oldMessageStream))
{
request.WriteMessage(xw);
xw.Flush();
messageBody = Encoding.UTF8.GetString(oldMessageStream.ToArray());
}
}

// Replace instances of 0.0.0.0 with actual remote endpoint address
messageBody = messageBody.Replace("0.0.0.0", remoteEndpointProperty.Address);

// NOTE: Do not close or dispose of this MemoryStream. It will be used by WCF down the line.
var newMessageStream = new MemoryStream(Encoding.UTF8.GetBytes(messageBody));
XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(newMessageStream, new XmlDictionaryReaderQuotas());

// Create a new message with our modified endpoint address and
// copy over existing properties and headers
Message newMessage = Message.CreateMessage(xdr, int.MaxValue, request.Version);
newMessage.Properties.CopyProperties(request.Properties);
newMessage.Headers.CopyHeadersFrom(request.Headers);
request = newMessage;
return null;
}

public void BeforeSendReply(ref Message reply, object correlationState)
{
}

public void Validate(ServiceEndpoint endpoint)
{
}

public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
}

此端点行为将原始 WCF 发现回复消息替换为副本,其中 0.0.0.0 的实例已替换为接收消息的地址,可在 RemoteEndpointMessageProperty< 中获得Address 属性。

要使用它,只需在创建 DiscoveryClient 时将新端点行为添加到 UdpDiscoveryEndpoint:

var udpDiscoveryEndpoint = new UdpDiscoveryEndpoint();
udpDiscoveryEndpoint.EndpointBehaviors.Add(new WcfDiscoveryAddressFixEndpointBehavior());
_discoveryClient = new DiscoveryClient(udpDiscoveryEndpoint);

// Proceed as usual.

关于c# - 使用 net.tcp ://0. 0.0.0 :0/blah announces net. tcp ://0. 0.0.0:0/blah 使用服务主机发现 WCF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16947565/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com