【发布时间】:2021-08-04 16:06:13
【问题描述】:
我正在尝试通过 signalR 连接到 Web 套接字连接。它在本地运行良好。旧版本甚至可以很好地部署在同一台机器上(同时)。这很重要,因为服务器 (2) 位于 AWS 负载均衡器之后。
错误信息如下:
与“wss://stg-api.guestbell.com/hubs/main?role-type=1&access_token=eyJhbG...”的 WebSocket 连接失败
当我在 Chrome 上打开网络 WS 部分时,我看到状态为“已完成”并且没有其他错误。恕我直言,这很奇怪,因为我期望 401/500... 或者当它不起作用时类似的东西。
代码: 前端:
connection = new HubConnectionBuilder()
.withUrl(
Config.apiUrl +
Config.signalRMainPath +
'?role-type=' +
RoleTypeEnum.Guest,
{
accessTokenFactory: () => store.getState().oidc.user?.access_token,
transport: HttpTransportType.WebSockets,
// I've tried various combinations of these
/*skipNegotiation: true,
withCredentials: true,*/
}
)
.withAutomaticReconnect({
nextRetryDelayInMilliseconds: retryContext => {
return Math.random() * 10000 + 5000;
},
})
.build();
...
await connection.start();
后端:
// Configure services
var signalRBuilder = services.AddSignalR();
// Configure
app.UseCors("CorsPolicy");
if (env.IsDevelopment()) {
app.UseSimulatedLatency(
min: TimeSpan.FromMilliseconds(100),
max: TimeSpan.FromMilliseconds(300)
);
} else {
app.UseHsts();
app.UseForwardedHeaders();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseDefaultFiles();
app.UseStaticFiles(new StaticFileOptions {
OnPrepareResponse = ctx => {
const int durationInSeconds = 60 * 60 * 24 * 30;
ctx.Context.Response.Headers[HeaderNames.CacheControl] =
"public,max-age=" + durationInSeconds;
}
});
app.UseSignalRQueryStringAuth();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => {
endpoints.MapHub < SignalRMainCore > ("/hubs/main");
endpoints.MapHealthChecks("/health");
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
我不知道我的问题在哪里?
我正在使用:
"@microsoft/signalr": "^5.0.6"
其他相关信息:
机器上的Dotnet版本:
C:\Users\Administrator>dotnet --info
.NET SDK (reflecting any global.json):
Version: 5.0.203
Commit: 383637d63f
Runtime Environment:
OS Name: Windows
OS Version: 10.0.17763
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.203\
Host (useful for support):
Version: 5.0.6
Commit: 478b2f8c0e
.NET SDKs installed:
5.0.203 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
编辑:
我注意到了一些奇怪的事情。当我复制 websockets URL 并将其粘贴到浏览器(将 wss 替换为 https)时,我得到:
Cannot change transports mid-connection
在它起作用的页面上(有道理,错误显然来自信号 r)
但是当我对不起作用的页面执行相同操作时,我得到了标准的 IIS 404:
现在这似乎很可疑……就像 IIS 以某种方式劫持了 HTTP 管道。奇怪的是相同的代码在我的本地机器上的 IIS 上工作。既表达又恰当。
可能是红鲱鱼......我不知道
编辑 2: 额外的小信息,协商工作,返回 200 和此响应:
{"negotiateVersion":1,"connectionId":"_5nQwxYYBAczXdW77JAGeQ","connectionToken":"GizQot1b0Gq2epsiM4BA3A","availableTransports":[{"transport":"WebSockets","transferFormats":["Text","Binary"]},{"transport":"ServerSentEvents","transferFormats":["Text"]},{"transport":"LongPolling","transferFormats":["Text","Binary"]}]}
这与服务器的设置方式一致。
【问题讨论】:
-
您是否在开发工具中检查过请求以查看其内容?您是否在 IIS 中安装了 WebSocket 支持?证书是否受信任?
-
是的,还有另一个站点在这些机器上具有完全相同的设置并且它在那里工作(它不是完全相同的代码,它是一个旧版本,但主要区别是从 dotnet 3.1 更新到5.0.6).
-
请注意我的编辑,也许有些事情会响起。谢谢@fredrik!
-
猜测 Frederik 的回答可能是正确的。默认情况下,IIS 主机通常没有启用 web-sockets 协议。确保您的 IIS 配置正确,请参阅 IIS/IIS Express Support 和 Websockets Fundamentals
-
绝对启用,就像我提到的那样,它可以在同一个 IIS 上托管的不同网站上运行
标签: c# asp.net-core .net-core signalr