Skip to content

Commit 673f38c

Browse files
committed
Improve SSDP robustness if IP address changes while server is already running (most likely DHCP)
1 parent f380381 commit 673f38c

File tree

1 file changed

+54
-31
lines changed

1 file changed

+54
-31
lines changed

MilwaukeeMakerspaceApi/Program.cs

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Reflection;
1212
using System.Security.Claims;
1313
using System.Text.Json;
14+
using System.Threading;
1415
using System.Threading.Tasks;
1516
using Microsoft.AspNetCore.Authentication;
1617
using Microsoft.AspNetCore.Authentication.Cookies;
@@ -219,7 +220,7 @@ public static int Main(string[] args)
219220

220221
var task = app.RunAsync();
221222

222-
PublishDevice();
223+
_ = PublishDevice();
223224

224225
task.GetAwaiter().GetResult();
225226
}
@@ -233,45 +234,67 @@ public static int Main(string[] args)
233234
}
234235

235236
// Call this method from somewhere to actually do the publish.
236-
private static void PublishDevice()
237+
private static Task PublishDevice()
237238
{
238-
try {
239-
var ip4 = GetLocalIp4Address();
240-
var version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
241-
242-
var deviceDefinition4 = new SsdpRootDevice() {
243-
Location = new Uri($"http://{ip4}/info/service"),
244-
PresentationUrl = new Uri($"http://{ip4}/"),
245-
FriendlyName = "Milwaukee Makerspace Api",
246-
Manufacturer = "Milwaukee Makerspace",
247-
ModelName = "Milwaukee Makerspace Api",
248-
Uuid = "6111f321-2cee-455e-b203-4abfaf14b516",
249-
ManufacturerUrl = new Uri("https://milwaukeemakerspace.org/"),
250-
ModelUrl = new Uri("https://github.com/DanDude0/MilwaukeeMakerspaceApi/"),
251-
ModelNumber = version,
252-
};
253-
254-
// Have to bind to all addresses on Linux, or broadcasts don't work!
255-
if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) {
256-
ip4 = IPAddress.Any.ToString();
257-
}
239+
return Task.Run(async () =>
240+
{
241+
try {
242+
var version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
243+
var oldIp4 = "";
244+
245+
while (true) {
246+
var ip4 = GetLocalIp4Address();
247+
248+
if (ip4 != oldIp4) {
249+
oldIp4 = ip4;
250+
SsdpPublisher4?.Dispose();
251+
SsdpPublisher4 = null;
252+
253+
var deviceDefinition4 = new SsdpRootDevice() {
254+
Location = new Uri($"http://{ip4}/info/service"),
255+
PresentationUrl = new Uri($"http://{ip4}/"),
256+
FriendlyName = "Milwaukee Makerspace Api",
257+
Manufacturer = "Milwaukee Makerspace",
258+
ModelName = "Milwaukee Makerspace Api",
259+
Uuid = "6111f321-2cee-455e-b203-4abfaf14b516",
260+
ManufacturerUrl = new Uri("https://milwaukeemakerspace.org/"),
261+
ModelUrl = new Uri("https://github.com/DanDude0/MilwaukeeMakerspaceApi/"),
262+
ModelNumber = version,
263+
};
258264

259-
Log.Information($"Publishing SSDP on {ip4}");
265+
// Have to bind to all addresses on Linux, or broadcasts don't work!
266+
if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) {
267+
ip4 = IPAddress.Any.ToString();
268+
}
260269

261-
SsdpPublisher4 = new SsdpDevicePublisher(new SsdpCommunicationsServer(new SocketFactory(ip4)));
262-
SsdpPublisher4.StandardsMode = SsdpStandardsMode.Relaxed;
263-
SsdpPublisher4.AddDevice(deviceDefinition4);
270+
Log.Information($"Now Publishing SSDP on {ip4}");
264271

265-
SsdpDescription = deviceDefinition4.ToDescriptionDocument();
266-
}
267-
catch (Exception ex) {
268-
Log.Fatal(ex, "Error publishing device over SSDP");
269-
}
272+
SsdpPublisher4 = new SsdpDevicePublisher(new SsdpCommunicationsServer(new SocketFactory(ip4)));
273+
SsdpPublisher4.StandardsMode = SsdpStandardsMode.Relaxed;
274+
SsdpPublisher4.AddDevice(deviceDefinition4);
275+
276+
SsdpDescription = deviceDefinition4.ToDescriptionDocument();
277+
}
278+
279+
await Task.Delay(60000);
280+
};
281+
}
282+
catch (Exception ex) {
283+
Log.Fatal(ex, "Error publishing device over SSDP");
284+
}
285+
});
270286
}
271287

272288
private static string GetLocalIp4Address()
273289
{
274290
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
291+
var count = 0;
292+
293+
while (NetworkInterface.GetIsNetworkAvailable() == false && count < 10) {
294+
Log.Information("Network not available, waiting for interface to go up.");
295+
count += 1;
296+
Thread.Sleep(5000);
297+
}
275298

276299
foreach (var network in networkInterfaces) {
277300
if (network.OperationalStatus != OperationalStatus.Up)

0 commit comments

Comments
 (0)