gpt4 book ai didi

c# - LAN 上的 Windows UWP Web 服务发现

转载 作者:太空宇宙 更新时间:2023-11-03 13:06:59 25 4
gpt4 key购买 nike

我正在尝试为本地网络上的客户端构建网络服务。对于该服务,我可以针对任何版本的 .NET Framework。客户端是移动 Windows 设备,我想使用通用 Windows 平台 (UWP) 作为目标框架。

该服务将在具有不同网络地址的多台机器上运行。我的目标是客户端一连接到本地网络就可以自动检测到服务。我想避免用户输入任何 ip 地址。但是我能找到的所有示例都使用硬编码的服务 URL。因为我没有 DNS 服务器,所以我必须将服务 IP 地址输入(或硬编码)到客户端。

我目前正在运行一个带有 UDPDiscoveryEndpoint 的 WCF 服务,这正是我想要的。但不幸的是,WCF 的那部分(System.ServiceModel.Discovery 命名空间)在 WinRT 上不可用,在通用 Windows 平台上也不支持。我不必使用 WCF;任何具有服务发现功能的替代库都是完美的。

所以这是我的问题:有没有办法在 WinRT/UWP 应用程序中的本地网络上进行服务发现?我尝试了 ASP.NET Web API 和 SignalR,但似乎这种基于 HTTP 的服务/框架根本不支持发现。

谢谢!

最佳答案

我已经设法使用套接字和广播消息在 UWP 中进行 Web 服务发现。

请检查my answer了解更多详情。

编辑 - 正如@naveen-vijay 所说,我发布了一个更完整的答案,而不仅仅是指向解决方案的链接。

每个 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 });
}
}
}
}
}

关于c# - LAN 上的 Windows UWP Web 服务发现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30452293/

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