错误:启动连接失败:错误:WebSocket 失败 连接。在服务器上找不到连接,或者 端点可能不是 SignalR 端点,连接 ID 不是 服务器上存在,或者存在阻止 WebSocket 的代理。如果你 让多个服务器检查粘性会话是否已启用。
WebSocketTransport.js:49 WebSocket 连接到 “ws://xxxxxx/生产/web-services/hubs/spreadhub”失败:
Angular.ts
ngOnInit(): void {
// For signalR Hub connection
this.connection = new HubConnectionBuilder()
.withUrl('http://xxx.xxx.com/production/web-services/hubs/spreadhub', { // localhost from **AspNetCore3.1 service**
skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets
})
.build();
this.connection.on('dataReceived', (data: string) => {
var model = JSON.parse(data);
});
this.connection.start().then(() => { // to start the server
console.log('server connected!!!');
}).catch(err => console.log(err));
}
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-7.0
您不需要指定完整的网址,只需指定您想要连接的集线器...假设您的集线器名称是 spreadhub 您只需要:
this.connection = new HubConnectionBuilder()
.withUrl('https://localhost:5001/spreadhub', { // localhost from **AspNetCore3.1 service**
skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets
})
.build();
在服务器上,如果部署到 azure,请不要忘记打开 websockets,例如:
在少数情况下我会遇到此错误,但没有进一步详细说明原因。
我可以通过挖掘找到一些解决我遇到的问题的方法。
不包括 SignalR (C#) 服务器端的
app.UseHttpsRedirection()
。 (请注意,这在生产中不是合适的解决方案。)这在您的开发环境中通常是需要的。
无效/过期
access token
。需要在 Hub 类的 AuthenticationSchemes
属性中定义 Authorize
。
代码:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class HubBase : Hub
{ }
accessTokenFactory
发送令牌。代码:
const connection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:5001/hub", {
skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets,
//Adding this line
accessTokenFactory: async () => { return this.token}
})
.build();
this.token
是您生成/获取并随请求发送的令牌。
我们发现,如果使用重定向 url 进行协商(例如,与
Azure SignalR Service
常见),还会出现这种异常的另一种情况。
如果在调用协商 url 和协商返回的重定向 url 之间需要几秒钟的时间,我们会收到此/类似的错误消息。我认为的原因是
Azure SignalR Service
不允许在后端通信后有很长的时间窗口供客户端连接。
尽管应该立即连接,但确实需要几秒钟的原因是因为 javascript 线程切换到对 DOM 进行一些大量更新,并且没有立即执行下一个调用。
如果您使用
createProxyMiddleware
,请不要忘记添加ws: true
:
const appProxy = createProxyMiddleware(context, {
target: 'https://localhost:7288',
secure: false,
ws: true
});
我使用 Visual Studio 的模板生成 ASP.NET Core + React 应用程序,它自动将
createProxyMiddleware
包含在 setupProxy.js
文件中
此问题是由于程序限制将 JWT 与 WebSockets/ServerSentEvents 结合使用而导致的。 这个问题的解决方法
.AddJwtBearer(configureOptions =>
{
configureOptions.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
configureOptions.TokenValidationParameters = tokenValidationParameters;
configureOptions.SaveToken = true;
configureOptions.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken)
&& path.StartsWithSegments("/hubs/spreadhub"))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};