我已经配置了跨应用程序
SignalR
(我使用内置SignalR)通信(不同端点上的webapp
和asp.net mvc
应用程序之间)。在本地它工作正常,不会在浏览器控制台中触发任何错误或警告。
当我将此应用程序部署到 azure 时,它仍然工作正常,但我在浏览器控制台中看到奇怪的错误(就在启动
UI
应用程序期间,在任何通信之前):
[ERROR]
* The connection to https://mywebapp.eastus-01.azurewebsites.net/NotificationHub?id=aaaaaaaaaaaaaaaaaaaa-g was interrupted while the page was loading. signalr.js:2446:31
* [2024-09-21T20:15:31.733Z] Information: Connection disconnected. signalr.js:453:30
* [2024-09-21T20:15:32.420Z] Information: SSE connected to https://mywebapp.eastus-01.azurewebsites.net/NotificationHub?id=s8Tsz4ASX_0G9QDnVp9o7g signalr.js:453:30
* [2024-09-21T20:15:33.475Z] Information: SSE connected to https://mywebapp.eastus-01.azurewebsites.net/NotificationHub?id=CJxP06m_KbrlaT59XgHqtw signalr.js:453:30
[WARNING]
* Source map error: Error: request failed with status 404
Resource URL: https://myuiapp.eastus-01.azurewebsites.net/lib/microsoft/signalr/dist/browser/signalr.js
Source Map URL: signalr.js.map
[WARNING]
* Source map error: request failed with status 404
Resource URL: https://myuiapp.eastus-01.azurewebsites.net/lib/microsoft/signalr/dist/browser/signalr.js
Source Map URL: signalr.js.map
正如我所说,它不会影响逻辑,因此可以正确接收来自
api
的通知,但我想知道这些错误/警告是关于什么的。
API
侧的配置(但正如我所说,在涉及任何通知步骤之前启动应用程序期间会触发此错误):
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "CorsSignalr", policyBuilder =>
policyBuilder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.SetIsOriginAllowed(hostName => true));
});
app.UseCors("CorsSignalr");
app.MapHub<NotificationHub>("/NotificationHub");
发送请求(在启动应用程序期间不调用):
var userGroupName = "name";
var group = _notificationHub.Clients.Group(userGroupName);
await group.SendAsync(
method: javascriptMethodName,
arg1: arg1,
...
userName);
UI
侧只有js配置(也没有cors
或其他signalr
相关配置):
let signalRHostName= document.getElementById("API_HOST_ADDRESS").value
var connection = new signalR.HubConnectionBuilder()
.withUrl(signalRHostName.concat("/NotificationHub"))
.withAutomaticReconnect()
.build();
在
azure web app
一侧,我看到signalr.js出现在wwwroot/wwwroot
文件夹中:
C:\home\site\wwwroot\wwwroot\lib\microsoft\signalr\dist\browser>ls
signalr.js
signalr.min.js
那么,如何解决这个问题呢?
更新1: 谢谢@LexLi,这看起来是一个继续的好主意,但我还不确定如何正确地做到这一点。我更改了 2 个地方的代码:
在
js
侧添加了运输:
var connection = new signalR.HubConnectionBuilder()
.withUrl(signalRHostName.concat("/NotificationHub"), {
transport: signalR.HttpTransportType.ServerSentEvents
})
.withAutomaticReconnect()
.build();
并以这种方式在
API
侧配置传输:
app.MapHub<NotificationHub>("/NotificationHub", (options) =>
{
options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.ServerSentEvents;
});
不再应用任何更改。如果配置 SSE 就足够了,控制台中的输出与消息序列(包括信息/警告/错误)100% 相同
更新2:
我在 _Layout.cshtml 中的页脚后面的
customSignalR.js
中调用创建连接:
<footer class="border-top footer text-muted">
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/lib/microsoft/signalr/dist/browser/signalr.js"></script>
<script src="~/js/customSignalR.js"></script>
@await RenderSectionAsync("Scripts", required: false)
在
customSignalR.js
内部的位置,我在文件开头创建 new signalR.HubConnectionBuilder
。
更新3:
在 js 端启用调试日志后,在启动应用程序期间我看到:
The connection to https://myapi.eastus-01.azurewebsites.net/NotificationHub?id=bbbb was interrupted while the page was loading. signalr.js:2446:31
[2024-09-23T05:23:53.574Z] Debug: HttpConnection.stopConnection(undefined) called while in state Connected. signalr.js:457:30
[2024-09-23T05:23:53.575Z] Information: Connection disconnected. signalr.js:453:30
[2024-09-23T05:23:53.575Z] Debug: HubConnection.connectionClosed(undefined) called while in state Connected. signalr.js:457:30
[2024-09-23T05:23:53.575Z] Information: Connection reconnecting. signalr.js:453:30
[2024-09-23T05:23:53.575Z] Information: Reconnect attempt number 1 will start in 0 ms. signalr.js:453:30
[2024-09-23T05:23:53.575Z] Debug: Starting connection with transfer format 'Text'. signalr.js:457:30
[2024-09-23T05:23:53.575Z] Debug: Sending negotiation request: https://myapi.eastus-01.azurewebsites.net/NotificationHub/negotiate?negotiateVersion=1. signalr.js:457:30
[2024-09-23T05:23:55.002Z] Debug: Starting HubConnection. signalr.js:457:30
[2024-09-23T05:23:55.004Z] Debug: Starting connection with transfer format 'Text'. signalr.js:457:30
[2024-09-23T05:23:55.004Z] Debug: Sending negotiation request: https://myapi.eastus-01.azurewebsites.net/NotificationHub/negotiate?negotiateVersion=1. signalr.js:457:30
[2024-09-23T05:23:55.371Z] Debug: Selecting transport 'ServerSentEvents'. signalr.js:457:30
[2024-09-23T05:23:55.556Z] Information: SSE connected to https://myapi.eastus-01.azurewebsites.net/NotificationHub?id=aaaa signalr.js:453:30
[2024-09-23T05:23:55.556Z] Debug: The HttpConnection connected successfully. signalr.js:457:30
[2024-09-23T05:23:55.556Z] Debug: Sending handshake request. signalr.js:457:30
[WARNING]
Source map error: Error: request failed with status 404
Resource URL: https://myuiapp.eastus-01.azurewebsites.net/lib/microsoft/signalr/dist/browser/signalr.js
Source Map URL: signalr.js.map
[2024-09-23T05:23:56.082Z] Information: Using HubProtocol 'json'. signalr.js:453:30
[2024-09-23T05:23:56.083Z] Debug: Server handshake complete. signalr.js:457:30
[2024-09-23T05:23:56.291Z] Debug: HubConnection connected successfully
听起来像
websocket
协议由于某种原因无法使用,并且 SSE 确实可以作为后备(虽然不确定为什么直接启用 SSE 没有帮助),有什么想法如何在 azure 应用程序服务上启用它吗?
更新4: 感谢@JasonPan,显然在azure应用程序服务中默认情况下未启用websockets,启用后,所有错误都消失了,唯一剩下的问题是一个警告:
Source map error: Error: request failed with status 404
Resource URL: https://myuiapp.eastus-01.azurewebsites.net/lib/microsoft/signalr/dist/browser/signalr.js
Source Map URL: signalr.js.map
此文件存在于天蓝色端,不确定为什么我会看到此 404 错误/警告?
从signalr客户端日志中,我们可以发现signalr连接是通过SSE进行的。这意味着不是代码问题。
然后我们需要在平台中启用webscoket功能,对于azure应用程序服务,我们可以在azure门户中配置它,如下所示。
还有
Source map error: Error: request failed with status 404
。