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

.NET Core中WebSocket下如何向SignalR Hub传递当前页面URL

问题解答

1. SignalR使用WebSocket传输时能否传递自定义头?

不能。WebSocket协议的握手阶段基于HTTP,但SignalR在使用WebSocket传输时,不会将自定义HTTP头传递到服务器端。这就是你通过headers配置的Page-Url在WebSocket模式下无法被服务器获取,而HTTP长轮询等其他传输方式可以正常获取的原因。

2. 传递自定义数据的替代方案

方案一:将数据附加到连接URL的查询参数中

这是最简单直接的方式,客户端在构建连接URL时把页面URL作为查询参数带上,服务器从HttpContext的查询集合中获取。

客户端代码(Angular):

const pageUrl = encodeURIComponent(window.location.href);
this.hubConnection = new signalR.HubConnectionBuilder()
  .withUrl(`${apiUrl}sharedconnectionhub?pageUrl=${pageUrl}`, {
    accessTokenFactory: () => accessToken,
    transport: signalR.HttpTransportType.WebSockets
  })
  .withAutomaticReconnect()
  .build();

服务端代码(.NET Core):

public class MyHub : Hub
{
    public override async Task OnConnectedAsync()
    {
        var httpContext = Context.GetHttpContext();
        if (httpContext != null)
        {
            if (httpContext.Request.Query.TryGetValue("pageUrl", out var pageUrl))
            {
                var decodedUrl = Uri.UnescapeDataString(pageUrl);
                Console.WriteLine($"Page URL: {decodedUrl}");
            }
        }
        
        await base.OnConnectedAsync();
    }
}

方案二:连接建立后主动调用Hub方法传递数据

在SignalR连接成功建立后,客户端主动调用服务器端的Hub方法,将页面URL等自定义数据发送过去。这种方式更灵活,适合需要传递较多数据的场景。

客户端代码(Angular):

this.hubConnection.start().then(() => {
    // 连接成功后调用服务器方法传递页面URL
    this.hubConnection.invoke('SendPageUrl', window.location.href)
        .catch(err => console.error(err));
}).catch(err => console.error(err));

服务端代码(.NET Core):

public class MyHub : Hub
{
    public override async Task OnConnectedAsync()
    {
        await base.OnConnectedAsync();
    }

    // 定义接收页面URL的方法
    public Task SendPageUrl(string pageUrl)
    {
        Console.WriteLine($"Page URL: {pageUrl}");
        // 可将URL与当前连接ID关联存储,供后续业务使用
        return Task.CompletedTask;
    }
}

方案三:使用JWT令牌携带自定义声明(若使用Token认证)

如果项目使用JWT作为访问令牌,可在令牌中添加自定义声明来携带页面URL,服务器端通过解析令牌获取数据。这种方式适合需要和身份认证绑定的场景。

客户端代码(Angular):

// 假设Token生成时已将pageUrl作为自定义声明添加
this.hubConnection = new signalR.HubConnectionBuilder()
  .withUrl(`${apiUrl}sharedconnectionhub`, {
    accessTokenFactory: () => accessToken, // 令牌包含pageUrl声明
    transport: signalR.HttpTransportType.WebSockets
  })
  .withAutomaticReconnect()
  .build();

服务端代码(.NET Core):

using System.Security.Claims;

public class MyHub : Hub
{
    public override async Task OnConnectedAsync()
    {
        var user = Context.User;
        if (user != null)
        {
            var pageUrlClaim = user.FindFirst("Page-Url");
            if (pageUrlClaim != null)
            {
                Console.WriteLine($"Page URL: {pageUrlClaim.Value}");
            }
        }
        
        await base.OnConnectedAsync();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:07:13