我正在尝试为本地网络上的客户端构建Web服务。对于服务,我可以针对任何版本的.NET Framework。客户端是移动Windows设备,我想使用通用Windows平台(UWP)作为目标框架。
该服务将在具有不同网络地址的多台计算机上运行。我的目标是客户端可以在连接到本地网络后立即自动检测服务。我想避免用户输入任何ip-address。但我能找到的所有样本都使用硬编码的服务URL。由于我没有DNS服务器,我必须将service-ip-address输入(或硬编码)到客户端。
目前我正在运行一个带有 UDPDiscoveryEndpoint 的WCF服务,这正是我想要的。但不幸的是,WCF的一部分( System.ServiceModel.Discovery 命名空间)在WinRT上不可用,并且在通用Windows平台上也不受支持。我不必使用WCF;任何具有服务发现功能的替代库都将是完美的。
所以这是我的问题:有没有办法在WinRT / UWP应用程序中的本地网络上进行服务发现?我尝试过ASP.NET Web API和SignalR,但似乎这个基于HTTP的服务/框架根本不支持发现。
谢谢!
答案 0 :(得分:1)
我已经设法使用套接字和广播消息在UWP中进行webservice发现。
请注意,请查看my answer了解详情。
编辑 - 正如@ naveen-vijay所说,我发布了一个更完整的aswer,而不仅仅是一个解决方案的链接。
每个WS都会侦听一个特定的端口,等待一些广播的消息搜索在LAN中运行的WS。 WS实现是win32,这是所需的代码:
private byte[] dataStream = new byte[1024];
private Socket serverSocket;
private void InitializeSocketServer(string id)
{
// Sets the server ID
this._id = id;
// Initialise the socket
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// Initialise the IPEndPoint for the server and listen on port 30000
IPEndPoint server = new IPEndPoint(IPAddress.Any, 30000);
// Associate the socket with this IP address and port
serverSocket.Bind(server);
// Initialise the IPEndPoint for the clients
IPEndPoint clients = new IPEndPoint(IPAddress.Any, 0);
// Initialise the EndPoint for the clients
EndPoint epSender = (EndPoint)clients;
// Start listening for incoming data
serverSocket.BeginReceiveFrom(this.dataStream, 0, this.dataStream.Length, SocketFlags.None, ref epSender, new AsyncCallback(ReceiveData), epSender);
}
private void ReceiveData(IAsyncResult asyncResult)
{
// Initialise the IPEndPoint for the clients
IPEndPoint clients = new IPEndPoint(IPAddress.Any, 0);
// Initialise the EndPoint for the clients
EndPoint epSender = (EndPoint)clients;
// Receive all data. Sets epSender to the address of the caller
serverSocket.EndReceiveFrom(asyncResult, ref epSender);
// Get the message received
string message = Encoding.UTF8.GetString(dataStream);
// Check if it is a search ws message
if (message.StartsWith("SEARCHWS", StringComparison.CurrentCultureIgnoreCase))
{
// Create a response messagem indicating the server ID and it's URL
byte[] data = Encoding.UTF8.GetBytes($"WSRESPONSE;{this._id};http://{GetIPAddress()}:5055/wsserver");
// Send the response message to the client who was searching
serverSocket.BeginSendTo(data, 0, data.Length, SocketFlags.None, epSender, new AsyncCallback(this.SendData), epSender);
}
// Listen for more connections again...
serverSocket.BeginReceiveFrom(this.dataStream, 0, this.dataStream.Length, SocketFlags.None, ref epSender, new AsyncCallback(this.ReceiveData), epSender);
}
private void SendData(IAsyncResult asyncResult)
{
serverSocket.EndSend(asyncResult);
}
客户端实现是UWP。我创建了以下类来进行搜索:
public class WSDiscoveryClient
{
public class WSEndpoint
{
public string ID;
public string URL;
}
private List<WSEndpoint> _endPoints;
private int port = 30000;
private int timeOut = 5; // seconds
/// <summary>
/// Get available Webservices
/// </summary>
public async Task<List<WSEndpoint>> GetAvailableWSEndpoints()
{
_endPoints = new List<WSEndpoint>();
using (var socket = new DatagramSocket())
{
// Set the callback for servers' responses
socket.MessageReceived += SocketOnMessageReceived;
// Start listening for servers' responses
await socket.BindServiceNameAsync(port.ToString());
// Send a search message
await SendMessage(socket);
// Waits the timeout in order to receive all the servers' responses
await Task.Delay(TimeSpan.FromSeconds(timeOut));
}
return _endPoints;
}
/// <summary>
/// Sends a broadcast message searching for available Webservices
/// </summary>
private async Task SendMessage(DatagramSocket socket)
{
using (var stream = await socket.GetOutputStreamAsync(new HostName("255.255.255.255"), port.ToString()))
{
using (var writer = new DataWriter(stream))
{
var data = Encoding.UTF8.GetBytes("SEARCHWS");
writer.WriteBytes(data);
await writer.StoreAsync();
}
}
}
private async void SocketOnMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
// Creates a reader for the incoming message
var resultStream = args.GetDataStream().AsStreamForRead(1024);
using (var reader = new StreamReader(resultStream))
{
// Get the message received
string message = await reader.ReadToEndAsync();
// Cheks if the message is a response from a server
if (message.StartsWith("WSRESPONSE", StringComparison.CurrentCultureIgnoreCase))
{
// Spected format: WSRESPONSE;<ID>;<HTTP ADDRESS>
var splitedMessage = message.Split(';');
if (splitedMessage.Length == 3)
{
var id = splitedMessage[1];
var url = splitedMessage[2];
_endPoints.Add(new WSEndpoint() { ID = id, URL = url });
}
}
}
}
}
答案 1 :(得分:0)
在UWP中,您可以使用PeerFinder类来发现LAN中应用程序的其他实例。
我知道这不完全是服务发现,它只是同行发现,但对于您的方案来说应该足够了。只需使用该应用程序的一个实例作为您的&#34;服务&#34;与其他实例通信。
您可以使用它来查找对等方并创建套接字连接:
$('#slider').slider().on('slideStop', function(ev){
var newVal = $('#slider').data('slider').getValue();
if(originalVal != newVal) {
document.querySelector(".image-optimised").src="imgd.php?src=disco-ballin-corrected--05.jpg&quality="+newVal+"&w=500&h=500&cf";
originalVal=newVal;
}
});
要更深入地了解同伴发现的工作原理,请结帐this链接[分钟6:30]。