我想通过signalR连接我的maui blazor应用程序(windows)到.net blazor服务器应用程序,这样我就可以将消息从服务器推送到客户端。我也用wpf dekstop app测试了一下,结果是一样的,握手失败。
我使用的版本:Microsoft.AspNetCore.SignalR.Client”Version=“6.0.1”,我尝试了7.0.1。
有趣的是,@localhost一切正常。而blazor wasm在同一台服务器上具有完整的信号R功能。
服务器端托管在@ akami
错误消息的详细信息:
Microsoft.AspNetCore.SignalR.Client.HubConnection: Trace: Waiting on Connection Lock in StartAsyncInner (/_/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs:247).
Microsoft.AspNetCore.SignalR.Client.HubConnection: Trace: The HubConnection is attempting to transition from the Disconnected state to the Connecting state.
Microsoft.AspNetCore.SignalR.Client.HubConnection: Debug: Starting HubConnection.
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Debug: Starting HttpConnection.
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Debug: Establishing connection with server at 'https://staging.vetat.work/hub/printertool'.
Microsoft.AspNetCore.Http.Connections.Client.Internal.LoggingHttpMessageHandler: Trace: Sending HTTP request POST 'https://staging.asd/hub/printertool/negotiate?negotiateVersion=1'.
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Debug: Established connection 'B07mkUpGtdoEwG6C9uQZbA' with the server.
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Debug: Starting transport 'WebSockets' with Url: https://staging.vetat.work/hub/printertool.
Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport: Information: Starting transport. Transfer mode: Text. Url: 'wss://staging.vetat.work/hub/printertool?id=UGcgq9uJEOL5hZkA1iZxCQ'.
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Error: Failed to start connection. Error starting transport 'WebSockets'.
System.Net.WebSockets.WebSocketException (0x80004005): The server returned status code '200' when status code '101' was expected.
at System.Net.WebSockets.WebSocketHandle.ValidateResponse(HttpResponseMessage response, String secValue, ClientWebSocketOptions options)
at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, HttpMessageInvoker invoker, CancellationToken cancellationToken, ClientWebSocketOptions options)
at System.Net.WebSockets.ClientWebSocket.ConnectAsyncCore(Uri uri, HttpMessageInvoker invoker, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport.DefaultWebSocketFactory(WebSocketConnectionContext context, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport.StartAsync(Uri url, TransferFormat transferFormat, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartTransport(Uri connectUrl, HttpTransportType transportType, TransferFormat transferFormat, CancellationToken cancellationToken)
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Debug: Skipping transport WebSockets because it failed to initialize.
System.Net.WebSockets.WebSocketException (0x80004005): The server returned status code '200' when status code '101' was expected.
at System.Net.WebSockets.WebSocketHandle.ValidateResponse(HttpResponseMessage response, String secValue, ClientWebSocketOptions options)
at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, HttpMessageInvoker invoker, CancellationToken cancellationToken, ClientWebSocketOptions options)
at System.Net.WebSockets.ClientWebSocket.ConnectAsyncCore(Uri uri, HttpMessageInvoker invoker, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport.DefaultWebSocketFactory(WebSocketConnectionContext context, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport.StartAsync(Uri url, TransferFormat transferFormat, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartTransport(Uri connectUrl, HttpTransportType transportType, TransferFormat transferFormat, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.SelectAndStartTransport(TransferFormat transferFormat, CancellationToken cancellationToken)
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Debug: Establishing connection with server at 'https://staging.asd/hub/printertool'.
Microsoft.AspNetCore.Http.Connections.Client.Internal.LoggingHttpMessageHandler: Trace: Sending HTTP request POST 'https://staging.asd/hub/printertool/negotiate?negotiateVersion=1'.
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Debug: Established connection 'trPpDN3vsUzTTUqSu0LdwQ' with the server.
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Debug: Starting transport 'ServerSentEvents' with Url: https://staging.asd/hub/printertool.
Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport: Information: Starting transport. Transfer mode: Text.
Microsoft.AspNetCore.Http.Connections.Client.Internal.LoggingHttpMessageHandler: Trace: Sending HTTP request GET 'https://staging.asd/hub/printertool?id=snz3w-l4JZ8sYDtO8cK9jQ'.
我试过maui应用程序,我试过调试,日志记录,wpf应用程序也。我希望我可以从服务器发送消息到客户端。
var url = _configuration[MauiConstants.AppConfig.SignalR];
_connection = new HubConnectionBuilder()
.WithUrl(url, options =>
{
options.AccessTokenProvider = () => Task.FromResult(token);
})
.ConfigureLogging(logging =>
{
// Log to the Console
logging.AddDebug();
// This will set ALL logging to Debug level
logging.SetMinimumLevel(LogLevel.Trace);
})
.WithAutomaticReconnect()
.Build();
对于授权,我使用不记名令牌
这是服务器配置:
if (config.SignalR.AllowCors)
{
_ = app.UseCors(builder =>
{
_ = builder.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins(config.SignalR.CorsAddress)
.SetIsOriginAllowedToAllowWildcardSubdomains();
});
}
_ = authenticationBuilder.AddJwtBearer(AuthConstant.Scheme.PrinterTool, options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.Audience = $"{Audience.PrinterTool:G}";
var signingKey = Convert.FromBase64String(secretKey);
options.TokenValidationParameters = new TokenValidationParameters
{
AuthenticationType = AuthConstant.Scheme.PrinterTool,
ValidateIssuer = false,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(signingKey),
ClockSkew = TimeSpan.FromMinutes(Convert.ToDouble(config.AdminAppAuthentication.ExpiresIn))
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers["Token-Expired"] = "true";
}
return Task.CompletedTask;
},
OnMessageReceived = context =>
{
//If the request is for our hub
var path = context.HttpContext.Request.Path;
if (path.StartsWithSegments(config.SignalR.PrinterToolMainHubRoute))
{
var authorization = context.Request.Headers?.Authorization.FirstOrDefault(a => a.StartsWith("Bearer "));
if (!string.IsNullOrEmpty(authorization))
{
context.Token = authorization.Substring("Bearer ".Length);
}
}
return Task.CompletedTask;
}
};
});
1条答案
按热度按时间abithluo1#
我想这个问题已经解决了。我也遇到了同样的问题,我解决了在prod服务器上更改nginx配置的问题
改变这一点:
通过这个:
完整的nginx配置:
来源:SignalR in ASP.NET Core behind Nginx