【发布时间】:2021-01-21 11:43:11
【问题描述】:
我创建事件映射座位预订并使用 SignalR 创建实时座位更新状态视图
我的广播中心
public class BroadcastHub : Hub
{
public async Task AddToGroup(string groupName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
}
public async Task RemoveFromGroup(string groupName)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
}
public async Task SeatUpdate(long SectinId, string groupName, long SeatId, SeatStatus seatStatus)
{
await Clients.OthersInGroup(groupName).SendAsync("ReceiveSeatUpdate", SectinId, SeatId, seatStatus);
}
}
组件
<div class="col-md-12 mb-3">
@((MarkupString)@SectionData.Salon.SalonMap)
</div>
...Seat Selection Murkup....
@code {
private HubConnection hubConnection;
public bool IsConnected => hubConnection.State == HubConnectionState.Connected;
Task SeatUpdate(long SectinId, string EventId, long SeatId, SeatStatus seatStatus) => hubConnection.SendAsync("SeatUpdate", SectinId, EventId, SeatId, seatStatus);
protected override async Task OnInitializedAsync()
{
SectionData.OnChange += StateHasChanged;
SectionData.Salon = await DataService.GetSalon();
action = GetSection;
foreach (var item in salon.Sections)
{
SectionData.Salon.SalonMap =salon.SalonMap.Replace(item.Action,$"onclick='app.GetSectionCallerJS({item.Id})'");
}
#region Hub
hubConnection = new HubConnectionBuilder().WithUrl(NavigationManager.ToAbsoluteUri("/broadcastHub")).Build();
hubConnection.On("ReceiveSeatUpdate", async (long SectinId, long SeatId, SeatStatus seatStatus) =>
{
if (SectionData.Section.Id == SectinId)
{
var Seat = SectionData.Section.Seats.Values.Where(x => x.Id == SeatId).FirstOrDefault();
Seat.SeatStatus = seatStatus;
}
StateHasChanged();
});
await hubConnection.StartAsync();
await hubConnection.SendAsync("AddToGroup", EventSansUniqueId);
#endregion Hub
}
#region GetSection
private static Action<long> action;
private void GetSection(long SectionId)
{
var section= salon.Sections.Where(x => x.Id == SectionId).FirstOrDefault();
SectionData.SetSection(section);
SectionData.Section.Seats = DataService.GetSection(SectionId);
StateHasChanged();
}
[JSInvokable]
public static void GetSectionCaller(long SectionId)
{
action.Invoke(SectionId);
}
#endregion GetSection
public void Dispose()
{
SectionData.OnChange -= StateHasChanged;
if (IsConnected) hubConnection.SendAsync("RemoveFromGroup", EventSansUniqueId);
}
}
JavaScript 是
window.app = {
GetSectionCallerJS: (id) => {
DotNet.invokeMethodAsync('KishApp.TRMS.Salon', 'GetSectionCaller', id);
}
};
问题是当集线器注册第二个,第三个和...时间DotNet.invokeMethodAsync调用最后注册的页面,而不是实际调用该方法并导致错误页面更新的页面
【问题讨论】:
-
您的
JSInvokable方法GetSectionCaller和action是静态的——您需要使用实例方法和实例Action 来确保代码在当前组件的上下文中运行。为此,您需要使用 JavaScriptapp对象注册当前组件的 DotNetObjectRef,以便它可以调用它。或者只是在 Blazor 中编写代码,而不是使用这种混合 JS 方法,那么您将不需要所有的互操作。 -
嗨@MisterMagoo,感谢您的回复。对于这种情况,我必须进行混合,因为沙龙地图是从数据库加载的 SVG,所以要在地图上选择一个部分,我需要混合解决方案。关于 DotNetObjectRef 我一直在尝试这样做,但是 int 没有成功,请您提供一个示例
标签: signalr blazor blazor-server-side