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

Blazor WebAssembly:实现客户端与服务端时间同步

最简单的解决方案:传递已流逝时长而非绝对开始时间

核心思路是绕开客户端与服务端的绝对时间同步问题,改用相对时间差来计算计时器数值:

  • 服务端不再返回存储的绝对启动时间,而是直接计算并返回「从启动时刻到当前服务端时间的已流逝秒数」
  • 客户端拿到这个初始已流逝时长后,记录自己本地的当前时间作为计时基准点
  • 后续客户端只需要用「本地当前时间与基准点的差值」加上「服务端返回的初始时长」,就能得到准确的总耗时

具体实现示例

ASP.NET Core API 修改

[HttpGet("timer/elapsed")]
public IActionResult GetElapsedTime()
{
    // serverStartTime为服务端已存储的启动时间(建议用UTC时间)
    var elapsed = (DateTime.UtcNow - serverStartTime).TotalSeconds;
    return Ok(new { ElapsedSeconds = elapsed });
}

Blazor 客户端逻辑

@page "/"
@inject HttpClient Http

<h3>已耗时:@_displayTime</h3>

@code {
    private string _displayTime;
    private double _initialElapsed;
    private DateTime _clientStart;

    protected override async Task OnInitializedAsync()
    {
        // 从服务端获取初始已流逝时长
        var result = await Http.GetFromJsonAsync<ElapsedResponse>("api/timer/elapsed");
        _initialElapsed = result.ElapsedSeconds;
        _clientStart = DateTime.UtcNow;
        
        // 启动定时更新
        _ = UpdateTimer();
    }

    private async Task UpdateTimer()
    {
        while (true)
        {
            // 计算本地流逝时间 + 初始时长
            var localElapsed = (DateTime.UtcNow - _clientStart).TotalSeconds;
            var total = _initialElapsed + localElapsed;
            
            // 格式化显示
            _displayTime = TimeSpan.FromSeconds(total).ToString(@"mm\:ss");
            StateHasChanged();
            await Task.Delay(1000);
        }
    }

    private class ElapsedResponse
    {
        public double ElapsedSeconds { get; set; }
    }
}

额外建议:全程使用UTC时间计算,避免不同时区带来的时间偏差,这个改动成本极低,还能避免很多潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 16:45:47