Aurelia 用 signalR 激活
Aurelia activate with signalR
如何将 signalR 与 aurelia canActivate() 和 activate() 页面循环一起使用?
我的意思是...在我的 VM 构造函数中,我初始化了 signalR 连接。在 canActivate() 或 activate() 方法中,我启动了 signalR 连接。在服务器端,在集线器中,当客户端连接时,我获取客户端的数据并将其发布到连接的客户端。所以Aurelia客户端会异步获取数据。所以页面会显示为空,数据来了会刷新。但是我想在显示页面之前等待来自 signalR hub 的数据。
所以工作流程是这样的:
- VM 构造函数 => 使用(HubConnectionBuilder)构建 signalR 连接
- VM Constructor => 设置连接事件,如 "onConnected"
- VM activate() => 通过调用 this.connection.start();
开始连接
- SignalR Hub.OnConnectedAsync() => 从数据库中获取数据
- SignalR Hub.OnConnectedAsync() => 仅将数据发送到新连接的客户端 ( Clients.Client(Context.ConnectionId).SendAsync("onConnected", data);)
- VM onConnected 事件处理程序 => 获取数据并设置模型 (this.model=data)
当工作流进行到第 4 步时,页面已经显示为空。
VM
@autoinject
export class AlarmsVM {
model: any;
connection: HubConnection;
constructor() {
this.connection = new HubConnectionBuilder()
.withUrl("/alarmsHub")
.configureLogging(LogLevel.Information)
.build();
this.connection.on("onConnected", (data) => this.model = data);
this.connection.on("onUpdate", (data) => this.model = data);
}
async activate() {
await this.connection.start().catch(err => console.error(err.toString()));
}
async deactivate() {
await this.connection.stop();
}
}
signalR 集线器
public class AlarmsHub:Hub
{
private readonly IMediator _mediator;
public AlarmsHub(IMediator mediator)
{
_mediator = mediator;
}
public override async Task OnConnectedAsync()
{
var data = await _mediator.Send(new GetAlarmsQuery());
await Clients.Client(Context.ConnectionId).SendAsync("onConnected", data);
}
...
}
根据文档,您可以 return 来自 activate() 的承诺,导航只会在承诺解决时发生:
https://aurelia.io/docs/api/router/interface/RoutableComponentActivate/method/activate/
编辑
我误读了你原来的问题,你基本上希望激活在收到 onConnected 事件时解决。
将 onConnected 的分辨率包装在 activate() 的 promise 中,你应该可以开始了,示例代码:
activate() {
this.connection.start().catch(err => console.error(err.toString()));
return new Promise((resolve, reject) => {
this.connection.on("onConnected", (data) => {
this.model = data;
return resolve();
});
});
}
如何将 signalR 与 aurelia canActivate() 和 activate() 页面循环一起使用? 我的意思是...在我的 VM 构造函数中,我初始化了 signalR 连接。在 canActivate() 或 activate() 方法中,我启动了 signalR 连接。在服务器端,在集线器中,当客户端连接时,我获取客户端的数据并将其发布到连接的客户端。所以Aurelia客户端会异步获取数据。所以页面会显示为空,数据来了会刷新。但是我想在显示页面之前等待来自 signalR hub 的数据。
所以工作流程是这样的:
- VM 构造函数 => 使用(HubConnectionBuilder)构建 signalR 连接
- VM Constructor => 设置连接事件,如 "onConnected"
- VM activate() => 通过调用 this.connection.start(); 开始连接
- SignalR Hub.OnConnectedAsync() => 从数据库中获取数据
- SignalR Hub.OnConnectedAsync() => 仅将数据发送到新连接的客户端 ( Clients.Client(Context.ConnectionId).SendAsync("onConnected", data);)
- VM onConnected 事件处理程序 => 获取数据并设置模型 (this.model=data)
当工作流进行到第 4 步时,页面已经显示为空。
VM
@autoinject
export class AlarmsVM {
model: any;
connection: HubConnection;
constructor() {
this.connection = new HubConnectionBuilder()
.withUrl("/alarmsHub")
.configureLogging(LogLevel.Information)
.build();
this.connection.on("onConnected", (data) => this.model = data);
this.connection.on("onUpdate", (data) => this.model = data);
}
async activate() {
await this.connection.start().catch(err => console.error(err.toString()));
}
async deactivate() {
await this.connection.stop();
}
}
signalR 集线器
public class AlarmsHub:Hub
{
private readonly IMediator _mediator;
public AlarmsHub(IMediator mediator)
{
_mediator = mediator;
}
public override async Task OnConnectedAsync()
{
var data = await _mediator.Send(new GetAlarmsQuery());
await Clients.Client(Context.ConnectionId).SendAsync("onConnected", data);
}
...
}
根据文档,您可以 return 来自 activate() 的承诺,导航只会在承诺解决时发生: https://aurelia.io/docs/api/router/interface/RoutableComponentActivate/method/activate/
编辑
我误读了你原来的问题,你基本上希望激活在收到 onConnected 事件时解决。 将 onConnected 的分辨率包装在 activate() 的 promise 中,你应该可以开始了,示例代码:
activate() {
this.connection.start().catch(err => console.error(err.toString()));
return new Promise((resolve, reject) => {
this.connection.on("onConnected", (data) => {
this.model = data;
return resolve();
});
});
}