Blazor SignalR 调用错误的 JSRuntime

Blazor SignalR Call Wrong JSRuntime

我创建事件映射座位预订并使用 SignalR 创建实时座位更新状态视图

我的 BroadcastHub

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 调用上次注册的页面,而不是实际调用该方法并导致错误页面更新的页面

感谢@MisterMango 我发现问题 GetSectionCaller 是一个静态方法,我必须在每次页面初始时创建新的 DotNetObjectReference 所以

DotNetObjectReference<Salon> ObjectReference;
  
protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await base.OnAfterRenderAsync(firstRender);
    if (firstRender)
    {
        ObjectReference = DotNetObjectReference.Create<Salon>(this);
        await JSRuntime.InvokeVoidAsync("app.setObjectReference", ObjectReference);
    }
}

[JSInvokable("GetSectionCaller")]
public void GetSectionCaller(long SectionId)
{
    GetSection(SectionId);
}

JavaScript

window.app = {
GetSectionCallerJS: (id) => {
    dotNetObject.invokeMethodAsync('GetSectionCaller', id);
},
setObjectReference: (ObjectReference) => {
    this.dotNetObject = ObjectReference;
}};