尝试建立组连接时 Azure SignalR InvokeAsync 挂起

问题描述

在连接上调用 InvokeAsync 挂起。

我参考以下 document 在 Azure SignalR 中配置组连接。

注意:

我只能在不依赖组配置的情况下建立连接。

客户:

YouCompleteMe unavailable: requires Vim compiled with Python (3.6.0+) support.

服务器:Azure 函数

var negotiateJson = await _client.GetStringAsync($"{host}{"negotiatefn"}");
var negotiate     = JsonConvert.DeserializeObject<NegotiateInfo>(negotiateJson);

var connection = new HubConnectionBuilder()
    .AddNewtonsoftJsonProtocol()
    .WithUrl(negotiate.Url,options => options.AccesstokenProvider = async () => negotiate.Accesstoken)
    .Build();

connection.Closed -= Connection_Closed;
connection.Closed += Connection_Closed;

connection.On<JObject>(hubMethodName,OnCourierUpdate);

await connection.StartAsync();
await connection.InvokeAsync("JoinGroup",sessionId); // HANGS APP HERE !!!

服务器:集线器

public static class LocationFn
{
    [FunctionName(nameof(LocationFn))]
    public static async Task<IActionResult> Run(
        [HttpTrigger(
            AuthorizationLevel.Anonymous,"post",Route = nameof(LocationFn))]
        HttpRequest req,[SignalR(HubName = "LocationHub")]
        IAsyncCollector<SignalRMessage> signalRMessages,ILogger log)
    {
        log.Loginformation($"{nameof(LocationFn)} has been invoked.");

        try
        {
            using (var streamReader = new StreamReader(req.Body))
            {
                var json = await streamReader.ReadToEndAsync();
                var subjectLocation = JsonConvert.DeserializeObject<SubjectLocation>(json);

                await signalRMessages.AddAsync(
                    new SignalRMessage
                    {
                        Target    = "LocationUpdate",GroupName = subjectLocation.SessionId,Arguments = new[] { subjectLocation }
                    });

                var message = Log(log,subjectLocation);

                return new OkObjectResult(message);
            }
        }
        catch (Exception ex)
        {
            return new BadRequestObjectResult("There was an error: " + ex.Message);
        }
    }
}



public static class JoinGroupFn
{
    [FunctionName(nameof(JoinGroupFn))]
    public static async Task<IActionResult> Run(
        [HttpTrigger(
            AuthorizationLevel.Anonymous,Route = nameof(JoinGroupFn))]
        HttpRequest req,ILogger log)
    {
        log.Loginformation($"{nameof(JoinGroupFn)} has been invoked.");

        try
        {
            var groupId = await req.ReadAsstringAsync();

            await signalRMessages.AddAsync(
                new SignalRMessage
                {
                    Target    = "JoinGroup",GroupName = groupId,Arguments = new[] { groupId }
                });

            log.Loginformation($"{nameof(JoinGroupFn)} {groupId}");

            return new OkObjectResult(groupId);
        }
        catch (Exception ex)
        {
            return new BadRequestObjectResult("There was an error: " + ex.Message);
        }
    }
}

解决方法

我来自 Azure SignalR 团队,您的服务在 Serverless 模式下运行,它不允许任何服务器连接,您的 F# 集线器如何运行?

而在客户端,connection.InvokeAsync 需要服务器确认,因为服务器连接无法连接,所以无法从服务获得任何确认。

如果您需要集线器服务器,请将服务切换到 Default 模式,然后使用 Azure SignalR SDK 运行集线器,并验证服务器已连接(通过服务指标中的日志或连接计数)。

如果你想要无服务器,请移除集线器,你可以在功能端添加无服务器集线器,参见:https://docs.microsoft.com/en-us/azure/azure-signalr/signalr-concept-serverless-development-config#class-based-model。 并且不要忘记设置上游,请参阅:https://docs.microsoft.com/en-us/azure/azure-signalr/concept-upstream#rule-settings