|
2 | 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
3 | 3 |
|
4 | 4 | using System;
|
| 5 | +using System.Net; |
| 6 | +using System.Net.Sockets; |
5 | 7 | using System.Runtime.InteropServices;
|
6 | 8 | using System.Text;
|
7 | 9 | using System.Threading.Tasks;
|
8 | 10 | using Microsoft.AspNetCore.Hosting;
|
| 11 | +using Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets; |
9 | 12 | using Microsoft.Extensions.Configuration;
|
10 | 13 | #if DATABASE
|
11 | 14 | using Npgsql;
|
@@ -106,6 +109,32 @@ public static IWebHost BuildWebHost(string[] args)
|
106 | 109 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
107 | 110 | {
|
108 | 111 | options.UnsafePreferInlineScheduling = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_NET_SOCKETS_INLINE_COMPLETIONS") == "1";
|
| 112 | + |
| 113 | + // Allow multiple processes bind to the same port. This also "works" on Windows in that it will |
| 114 | + // prevent address in use errors and hand off to another process if no others are available, |
| 115 | + // but it wouldn't round-robin new connections between processes like it will on Linux. |
| 116 | + options.CreateBoundListenSocket = endpoint => |
| 117 | + { |
| 118 | + if (endpoint is not IPEndPoint ip) |
| 119 | + { |
| 120 | + return SocketTransportOptions.CreateDefaultBoundListenSocket(endpoint); |
| 121 | + } |
| 122 | + |
| 123 | + // Normally, we'd call CreateDefaultBoundListenSocket for the IPEndpoint too, but we need |
| 124 | + // to set ReuseAddress before calling bind, and CreateDefaultBoundListenSocket calls bind. |
| 125 | + var listenSocket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp); |
| 126 | + |
| 127 | + // Kestrel expects IPv6Any to bind to both IPv6 and IPv4 |
| 128 | + if (ip.Address.Equals(IPAddress.IPv6Any)) |
| 129 | + { |
| 130 | + listenSocket.DualMode = true; |
| 131 | + } |
| 132 | + |
| 133 | + listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); |
| 134 | + listenSocket.Bind(ip); |
| 135 | + |
| 136 | + return listenSocket; |
| 137 | + }; |
109 | 138 | }
|
110 | 139 | });
|
111 | 140 |
|
|
0 commit comments