我在我的 Web 项目中使用 SignalR 创建了一个集线器。在我的集线器类中,我想接收在端口号 4001 上发送的 udp 数据。请建议通过 udp 套接字接收数据的代码。我尝试使用如下所示的代码接收,但它给出了错误“System.Net.Sockets.SocketException:'通常只允许每个套接字地址(协议/网络地址/端口)的一次使用”
ClockHub.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace RealTimeClock.App_Code
{
public class ClockHub : Hub
{
public void getSocketData()
{
// Here I want to receive udp socket data on port 4001
// my code commented here did not work
//UdpClient receivingUdpClient = new UdpClient(11000);
//IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
//Byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
//string UDP_Rx_Data= Encoding.ASCII.GetString rceiveBytes);
Clients.Caller.setTime(UDP_Rx_Data);
}
}
}
您可以使用中介应用程序接收 UDP 数据包,然后将它们转发到 SignalR Hub。
可以使用任务计划程序设置为自动重启的中间应用程序:
using Microsoft.AspNet.SignalR.Client;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace UdpToSignalR
{
internal class Program
{
private static readonly string hubURL = System.Configuration.ConfigurationManager.AppSettings["HubURL"];
private static readonly int listenPort = int.Parse(System.Configuration.ConfigurationManager.AppSettings["UDPPort"]);
private static void StartListener(IHubProxy hub)
{
UdpClient listener = new UdpClient(listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
try
{
while (true)
{
byte[] bytes = listener.Receive(ref groupEP);
hub.Invoke("getSocketData", Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
}
catch (SocketException e)
{
Console.WriteLine(e);
}
finally
{
listener.Close();
Environment.Exit(0);
}
}
public static void Main()
{
HubConnection connection = new HubConnection(hubURL);
var hub = connection.CreateHubProxy("ClockHub");
connection.StateChanged += (state) =>
{
Console.WriteLine($"State Changed: {state.NewState}");
};
connection.Reconnecting += () =>
{
Console.WriteLine("Reconnecting....");
};
connection.Closed += () =>
{
// If we loose hub connection close the app so that the task scheduler can fire it up again.
Environment.Exit(0);
};
connection.Start().Wait();
StartListener(hub);
}
}
}
此代码从应用程序配置中获取您的集线器 url 和 UDP 端口:
<appSettings>
<add key="UDPPort" value="4001"/>
<add key="HubURL" value="http://localhost:54856/signalr"/>
</appSettings>
您的中心代码将是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace RealTimeClock.App_Code
{
public class ClockHub : Hub
{
public Task getSocketData(string message)
{
Clients.Caller.setTime(message);
}
}
}