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

Azure Functions独立进程:SignalR客户端调用组函数问题求助

Azure Functions独立进程SignalR客户端加入/退出组的正确实现

核心问题分析

你现有的代码存在两个关键问题:

  1. 客户端未通过Azure Functions SignalR必需的Negotiate流程获取有效连接信息,直接连接函数端点无法建立SignalR连接
  2. SendToGroup函数仅用于向组发送消息,并非用于将客户端加入组的逻辑,需要专门的组管理函数

步骤1:服务端添加必要函数

1.1 Negotiate函数(获取SignalR连接凭证)

这是客户端连接Azure SignalR服务的必备入口:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
using System.Net;
using System.Text.Json;

[Function("Negotiate")]
public static HttpResponseData Negotiate(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req,
    [SignalRConnectionInfo(HubName = "serverless", ConnectionStringSetting = "AzureSignalRConnectionString")] SignalRConnectionInfo connectionInfo)
{
    var response = req.CreateResponse(HttpStatusCode.OK);
    response.WriteAsJsonAsync(connectionInfo);
    return response;
}

1.2 加入组的函数(两种实现方式)

方式A:客户端直接调用的SignalR触发函数

适用于客户端通过SignalR Hub方法调用加入组:

[Function("AddToGroup")]
[SignalROutput(HubName = "serverless", ConnectionStringSetting = "AzureSignalRConnectionString")]
public static SignalRGroupAction AddToGroup(
    [SignalRTrigger("serverless", "messages", "AddToGroup", ParameterNames = new[] { "groupName" })] SignalRInvocationContext invocationContext,
    string groupName)
{
    // 通过invocationContext获取当前连接的ConnectionId,自动关联当前客户端
    return new SignalRGroupAction(SignalRGroupActionType.Add)
    {
        GroupName = groupName,
        ConnectionId = invocationContext.ConnectionId
    };
}
方式B:HTTP触发函数

适用于通过HTTP请求触发加入组(比如服务端主动管理组):

public class GroupRequest
{
    public string ConnectionId { get; set; }
    public string GroupName { get; set; }
}

[Function("AddToGroupHttp")]
[SignalROutput(HubName = "serverless", ConnectionStringSetting = "AzureSignalRConnectionString")]
public static SignalRGroupAction AddToGroupHttp(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    using var reader = new StreamReader(req.Body);
    var body = reader.ReadToEnd();
    var request = JsonSerializer.Deserialize<GroupRequest>(body);

    return new SignalRGroupAction(SignalRGroupActionType.Add)
    {
        GroupName = request.GroupName,
        ConnectionId = request.ConnectionId
    };
}

1.3 退出组的函数

和加入组逻辑类似,仅修改操作类型:

[Function("RemoveFromGroup")]
[SignalROutput(HubName = "serverless", ConnectionStringSetting = "AzureSignalRConnectionString")]
public static SignalRGroupAction RemoveFromGroup(
    [SignalRTrigger("serverless", "messages", "RemoveFromGroup", ParameterNames = new[] { "groupName" })] SignalRInvocationContext invocationContext,
    string groupName)
{
    return new SignalRGroupAction(SignalRGroupActionType.Remove)
    {
        GroupName = groupName,
        ConnectionId = invocationContext.ConnectionId
    };
}

步骤2:修正客户端代码

客户端需要先完成Negotiate流程,再建立连接并调用组管理方法:

using Microsoft.AspNetCore.SignalR.Client;
using System.Net.Http.Json;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;

// 1. 调用Negotiate获取连接信息
var httpClient = new HttpClient();
var negotiateResponse = await httpClient.PostAsJsonAsync("http://localhost:7071/api/Negotiate", new { });
var connectionInfo = await negotiateResponse.Content.ReadFromJsonAsync<SignalRConnectionInfo>();

// 2. 建立SignalR连接
var _connection = new HubConnectionBuilder()
    .WithUrl(connectionInfo.Url, options =>
    {
        options.AccessTokenProvider = () => Task.FromResult(connectionInfo.AccessToken);
    })
    .Build();

// 3. 注册接收组消息的回调
_connection.On<string>("newMessage", message =>
{
    // 处理收到的组消息,例如打印到控制台
    Console.WriteLine($"收到组消息:{message}");
});

// 4. 启动连接
await _connection.StartAsync();

// 5. 调用服务端方法加入组
await _connection.InvokeAsync("AddToGroup", "groupToSend");

// 6. (可选)调用服务端方法退出组
// await _connection.InvokeAsync("RemoveFromGroup", "groupToSend");

验证消息发送

你原有的SendToGroup函数可以保留,当客户端加入组后,调用该函数即可向组发送消息,客户端会收到注册的newMessage回调。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:45:25