我创建了一个连接到 Intranet 上的 WCF Web 服务的通用应用程序,它工作得很好,因为服务主机的地址是已知的。
出于性能和安全(冗余)原因,系统架构允许多个 Web 服务在不同主机上运行。因此,我试图让我的应用程序发现在同一 LAN 上运行的给定契约(Contract)的每项服务,但我无法做到这一点。
我正在尝试在非常相似的 win32 应用程序中使用相同的方法:
var discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
var findCriteria = new FindCriteria(typeof(INewProdColetorWCFService));
findCriteria.Duration = TimeSpan.FromSeconds(5);
var findResponse = await discoveryClient.FindTaskAsync(findCriteria);
Visual Studio“自动”为我添加所需的引用 (System.ServiceModel.Discovery) as seen here
在设计时似乎没问题,但是当我尝试编译时,出现错误:
Cannot find type System.ServiceModel.Configuration.ServiceModelConfigurationElementCollection`1 in module System.ServiceModel.dll.
你们有人在 UWP 中这样做过吗?你能帮助我吗? 预先感谢,iuri。
ps:我已发布this question in MSDN也是
最佳答案
我自己做一些研究时发现了这个帖子。阅读 https://en.wikipedia.org/wiki/WS-Discovery 后并使用 Wireshark 破译一些细节,我得到了支持 Microsoft WS-Discovery 规范的基本概念证明,这意味着服务器端无需进行任何更改。
我现在已经退出了这个项目,但希望有人能从中得到一些用处:
public class WSDiscoveryResponse
{
private readonly string
_content,
_remotePort;
private readonly HostName
_remoteAddress;
public WSDiscoveryResponse(string content, HostName remoteAddress, string remotePort)
{
this._content = content;
this._remoteAddress = remoteAddress;
this._remotePort = remotePort;
}
}
public class WSDiscoveryClient
{
private const string
SRC_PORT = "0",//represents 'use any port available'
DEST_IP_WSDISCOVERY = "239.255.255.250", //broadcast (ish)
DEST_PORT_WSDISCOVERY = "3702";
private TimeSpan _timeout = TimeSpan.FromSeconds(5);
private List<WSDiscoveryResponse> _wsresponses = null;
/// <summary>
/// Get available Webservices
/// </summary>
public async Task<List<WSDiscoveryResponse>> GetAvailableWSEndpoints()
{
_wsresponses = new List<WSDiscoveryResponse>();
using (var socket = new DatagramSocket())
{
try
{
socket.MessageReceived += SocketOnMessageReceived;
//listen for responses to future message
await socket.BindServiceNameAsync(SRC_PORT);
//broadcast interrogation
await SendDiscoveryMessage(socket);
//wait for broadcast responses
await Task.Delay(_timeout).ConfigureAwait(false);
}
catch (Exception ex)
{
SocketErrorStatus webErrorStatus = SocketError.GetStatus(ex.GetBaseException().HResult);
}
}
return _wsresponses;
}
private string BuildDiscoveryMessage()
{
const string outgoingMessageFormat = @"<s:Envelope xmlns:s=""http://www.w3.org/2003/05/soap-envelope"" xmlns:a=""http://www.w3.org/2005/08/addressing""><s:Header><a:Action s:mustUnderstand=""1"">http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Probe</a:Action><a:MessageID>urn:uuid:{0}</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand=""1"">urn:docs-oasis-open-org:ws-dd:ns:discovery:2009:01</a:To></s:Header><s:Body><Probe xmlns=""http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01""><d:Types xmlns:d=""http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01"" xmlns:dp0=""http://tempuri.org/"">dp0:IDiscoveryService</d:Types><Duration xmlns=""http://schemas.microsoft.com/ws/2008/06/discovery"">PT5S</Duration></Probe></s:Body></s:Envelope>";
string outgoingMessage = string.Format(outgoingMessageFormat, Guid.NewGuid().ToString());
return outgoingMessage;
}
private async Task SendDiscoveryMessage(DatagramSocket socket)
{
using (var stream = await socket.GetOutputStreamAsync(new HostName(DEST_IP_WSDISCOVERY), DEST_PORT_WSDISCOVERY))
{
string message = BuildDiscoveryMessage();
var data = Encoding.UTF8.GetBytes(message);
using (var writer = new DataWriter(stream))
{
writer.WriteBytes(data);
await writer.StoreAsync();
}
}
}
private void SocketOnMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
var dr = args.GetDataReader();
string message = dr.ReadString(dr.UnconsumedBufferLength);
_wsresponses.Add(new WSDiscoveryResponse(message, args.RemoteAddress, args.RemotePort));
}
}
关于c# - UWP 应用中的 WCF 发现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37285149/