You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server如何获取窗口会话唯一ID,避免触发源窗口收到Toast提示?

Blazor Server 区分同一用户不同浏览器窗口的实现方案
  • 利用sessionStorage存储窗口唯一ID:sessionStorage是浏览器窗口级别的存储,每个窗口独立,关闭窗口后自动清除,完美匹配需求。
  • 客户端生成并维护窗口ID:通过JSInterop在客户端初始化时生成UUID作为窗口ID,存入sessionStorage,确保每个窗口有唯一标识。
  • 服务端传递过滤标识:发送Toast事件时携带触发窗口的originationID,其他客户端收到后对比自身窗口ID,匹配则忽略提示。

具体实现步骤

1. 客户端JS逻辑(wwwroot/js/windowId.js)

window.getWindowId = () => {
    let windowId = sessionStorage.getItem('BlazorWindowId');
    if (!windowId) {
        // 生成UUID作为唯一窗口ID
        windowId = crypto.randomUUID();
        sessionStorage.setItem('BlazorWindowId', windowId);
    }
    return windowId;
};

2. Blazor组件中获取窗口ID

在需要使用窗口ID的组件(或全局服务)中,通过JSInterop获取并存储:

@inject IJSRuntime JS
@inject IToastEventService ToastEventService // 自定义的事件服务

private string _currentWindowId;

protected override async Task OnInitializedAsync()
{
    // 获取当前窗口ID
    _currentWindowId = await JS.InvokeAsync<string>("getWindowId");
    
    // 订阅Toast事件,处理过滤逻辑
    ToastEventService.OnToastReceived += HandleToastReceived;
}

private void HandleToastReceived(ToastNotification toast)
{
    // 如果触发窗口ID与当前窗口ID一致,忽略提示
    if (toast.OriginationId == _currentWindowId)
        return;
    
    // 显示Toast提示逻辑
    ShowToast(toast);
}

public void Dispose()
{
    ToastEventService.OnToastReceived -= HandleToastReceived;
}

3. 发送Toast事件时携带originationID

当用户更新资源触发事件时,将当前窗口ID作为originationID传入:

public class ToastEventService
{
    public event Action<ToastNotification> OnToastReceived;

    public void SendToast(ToastNotification toast)
    {
        OnToastReceived?.Invoke(toast);
    }
}

// 资源更新时触发
public async Task UpdateResource()
{
    // 业务逻辑...
    
    // 获取当前窗口ID
    var originationId = await JS.InvokeAsync<string>("getWindowId");
    var toast = new ToastNotification
    {
        Message = "资源已更新,是否刷新视图?",
        OriginationId = originationId,
        UserId = CurrentUserId // 用于跨用户过滤
    };
    
    // 推送事件给所有客户端
    ToastEventService.SendToast(toast);
}

4. 未登录用户登录后的处理

未登录用户的窗口ID已存储在sessionStorage中,登录后无需重新生成,只需将窗口ID与当前用户ID关联即可。后续推送事件时,即使是登录后的用户,只要窗口ID与originationID不同,仍会收到提示。

替代方案:利用CircuitId

Blazor Server中每个窗口对应一个独立的Circuit,可通过CircuitAccessor获取CircuitId:

@inject Microsoft.AspNetCore.Components.Server.Circuits.ICircuitAccessor CircuitAccessor

private string _circuitId;

protected override void OnInitialized()
{
    _circuitId = CircuitAccessor.Circuit?.Id;
}

但CircuitId会在页面刷新、重连时变化,而sessionStorage的窗口ID仅在窗口关闭时失效,更符合“窗口会话唯一”的需求。

内容的提问来源于stack exchange,提问作者user101289

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 16:46:13