Httpcontext geht bei der Verwendung eines WebSockets mit .Net Core Cluster verloren
Posted: 25 Jan 2025, 12:25
Ich habe lange nach einer Lösung für dieses Problem gesucht und frage nun hier. Vielleicht hat hier jemand ein ähnliches Problem und kann mir einen Rat geben.
Zur Konfiguration:
Wir haben drei Windows-Server, die wir selbst betreiben. Auf diesen Servern hosten wir verschiedene C#-APIs mit .Net 8 und IIS. Alle drei Server sind identisch konfiguriert. Hier wird auch ein RabbitMQ-Cluster gehostet.
Cloudflare wird als Load Balancer verwendet, jedoch ohne Sitzungsaffinität, da ein Proxy erforderlich ist und wir diesen nicht verwenden möchten. Soweit so gut.
Nun zum Problem:
Die API, die der RabbitMQ-Cluster verwendet, stellt über localhost mithilfe von Rebus eine Verbindung zur lokalen RabbitMQ-Instanz her. Soweit ich weiß, werden die Nachrichten im Cluster automatisch an alle Knoten verteilt.
Der Zugriff auf die API erfolgt über eine NextJS-App über einen Hub mit Signalr. Erfolgt nun der Zugriff über den Load Balancer, dann ist nach einigen Aktualisierungen der Seite der Httpcontext im Httpcontextaccessor plötzlich Null. Dies geschieht auch, wenn der Zielhost nicht geändert wird.
Zur Konfiguration:
Wir haben drei Windows-Server, die wir selbst betreiben. Auf diesen Servern hosten wir verschiedene C#-APIs mit .Net 8 und IIS. Alle drei Server sind identisch konfiguriert. Hier wird auch ein RabbitMQ-Cluster gehostet.
Cloudflare wird als Load Balancer verwendet, jedoch ohne Sitzungsaffinität, da ein Proxy erforderlich ist und wir diesen nicht verwenden möchten. Soweit so gut.
Nun zum Problem:
Die API, die der RabbitMQ-Cluster verwendet, stellt über localhost mithilfe von Rebus eine Verbindung zur lokalen RabbitMQ-Instanz her. Soweit ich weiß, werden die Nachrichten im Cluster automatisch an alle Knoten verteilt.
Code: Select all
[...]
services
.AddSignalR( _ => {
_.EnableDetailedErrors = true;
} )
.AddMessagePackProtocol( _ => {
_.SerializerOptions = MessagePackSerializerOptions.Standard
.WithSecurity( MessagePackSecurity.UntrustedData );
} )
.AddRebusBackplane(); // changed for post
[...]
string rabbitMqConnectionString = $"amqp://rabbit:carrot@localhost:5672/myvhost"; // changed for post
services.AddRebus( configure => configure
.Transport( x => {
x.UseRabbitMq( rabbitMqConnectionString, GenerateTransientQueueName( "queuename" ) )
.InputQueueOptions( o => {
o.SetAutoDelete( true );
o.SetDurable( false );
} );
} ) );
services.AddSingleton();
[...]
app.UseEndpoints( endpoints => {
endpoints.MapControllers();
endpoints.MapHub( "/myhub" ); // changed for post
} );
[...]
Code: Select all
[...]
_httpContextAccessor = httpContextAccessor;
_context = context;
_securityService = securityService;
Claim[]? claims = _httpContextAccessor.HttpContext?.User.Claims.ToArray();
if (_httpContextAccessor == null) throw new Exception( "Httpcontextaccessor is null" );
if (_httpContextAccessor.HttpContext == null) throw new Exception( "Httpcontextaccessor => Httpcontext is null" ); // mytoken,
skipNegotiation: true, //