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

如何将WPF应用连接至Azure SignalR Service?

解决方案:WPF直接连接Azure SignalR Service(无服务器模式)

Azure SignalR Service本身是中继服务,无法直接作为独立Hub服务器使用。如果你不想部署自建后端,可以采用Azure Functions + Azure SignalR Service无服务器模式实现,以下是具体步骤:

1. 配置Azure SignalR Service为无服务器模式

  • 登录Azure Portal,找到你的SignalR Service实例
  • 进入「设置」页面,将「服务模式」改为无服务器,保存配置

2. 创建Azure Functions项目(处理消息逻辑)

新建Azure Functions项目,添加两个核心函数:

(1)Negotiate函数(用于客户端获取连接凭证)

该函数为WPF客户端提供合法的SignalR连接URL和AccessToken:

[FunctionName("Negotiate")]
public static SignalRConnectionInfo Negotiate(
    [HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req,
    [SignalRConnectionInfo(HubName = "draftchat")] SignalRConnectionInfo connectionInfo)
{
    return connectionInfo;
}

(2)SendMessage函数(用于广播消息)

该函数接收客户端发送的消息,通过SignalR Service广播给所有在线客户端:

[FunctionName("SendMessage")]
public static async Task SendMessage(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
    [SignalR(HubName = "draftchat")] IAsyncCollector<SignalRMessage> signalRMessages)
{
    var body = await new StreamReader(req.Body).ReadToEndAsync();
    var messageObj = JsonConvert.DeserializeObject<Message>(body);
    
    await signalRMessages.AddAsync(new SignalRMessage
    {
        Target = "ReceiveMessage",
        Arguments = new[] { messageObj.User, messageObj.Message }
    });
}

public class Message
{
    public string User { get; set; }
    public string Message { get; set; }
}

配置Functions连接字符串

在Azure Functions应用的「配置」页面,添加名为AzureSignalRConnectionString的应用设置,值为你SignalR Service实例的连接字符串(从SignalR实例的「密钥」页面获取)。

3. 修改WPF客户端代码

客户端需要先调用Negotiate接口获取合法连接信息,再建立SignalR连接:

private HubConnection? _connection;

private async Task ConnectToSignalR()
{
    // 调用Functions的Negotiate接口获取连接凭证
    var negotiateClient = new HttpClient();
    var negotiateResponse = await negotiateClient.GetFromJsonAsync<SignalRConnectionInfo>(
        "https://你的函数应用名称.azurewebsites.net/api/negotiate");

    if (negotiateResponse == null)
    {
        Messages.Items.Add("获取连接凭证失败");
        return;
    }

    // 使用凭证创建SignalR连接
    _connection = new HubConnectionBuilder()
        .WithUrl(negotiateResponse.Url, options =>
        {
            options.AccessTokenProvider = () => Task.FromResult(negotiateResponse.AccessToken);
        })
        .WithAutomaticReconnect()
        .Build();

    // 监听消息推送
    _connection.On<string, string>("ReceiveMessage", (user, message) =>
    {
        Dispatcher.Invoke(() =>
        {
            Messages.Items.Add($"{user}: {message}");
        });
    });

    try
    {
        await _connection.StartAsync();
        Messages.Items.Add("连接成功");
        openConnection.IsEnabled = false;
        sendMessage.IsEnabled = true;
    }
    catch (Exception ex)
    {
        Messages.Items.Add($"连接失败: {ex.Message}");
    }
}

// 发送消息方法
private async Task SendMessageAsync(string user, string message)
{
    if (_connection == null || _connection.State != HubConnectionState.Connected)
    {
        Messages.Items.Add("未连接到SignalR服务");
        return;
    }

    // 调用Functions的SendMessage接口发送消息
    var httpClient = new HttpClient();
    await httpClient.PostAsJsonAsync(
        "https://你的函数应用名称.azurewebsites.net/api/sendmessage", 
        new { User = user, Message = message });
}

// 用于接收Negotiate返回数据的模型
public class SignalRConnectionInfo
{
    public string Url { get; set; }
    public string AccessToken { get; set; }
}

关键说明

  • 你之前直接连接SignalR Service地址失败的核心原因:缺少合法的身份凭证(AccessToken),且无后端Hub处理连接请求。
  • 无服务器模式下,所有Hub方法调用必须通过Azure Functions转发,SignalR Service仅负责消息中继。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:21:00