skip to Main Content

I have a SignalR service that uses IHostedService to access SignalR on Azure. I’m trying to implement a Negotiate function that returns SignalRConnectionInfo. Problem is i need to pass the UserId into the ConnectionInfo but i don’t know it yet when filling in parameters. I’m using .NET 8 in Isolated mode and following these Microsoft docs.

Function

[Function("Negotiate")]
public static string Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req,
    [SignalRConnectionInfoInput(HubName = "SomeHub", UserId = "????")] string connectionInfo)
{
    Guid userId = // Get userId from database
    await signalRService.AddUserToGroupAll(userId);
    return connectionInfo; // How to get this when i don't know UserId in the parameters yet??
}

SignalRService

public class SignalRService(IConfiguration configuration)
{
    private ServiceHubContext _messageHubContext;

    public async Task AddUserToGroupAll(Guid userId)
    {
        await _messageHubContext.Groups.AddToGroupAsync(userId.ToString(), /** groupname **/);
    }

    #region IHostService Functions
    async Task IHostedService.StartAsync(CancellationToken cancellationToken)
    {
        using ServiceManager serviceManager = new ServiceManagerBuilder()
            .WithOptions(o => o.ConnectionString = configuration[ConfigurationConstants.AzureSignalRConnectionString])
            .BuildServiceManager();
        _messageHubContext = await serviceManager.CreateHubContextAsync("SomeHub", cancellationToken);
    }

    public async Task StopAsync(CancellationToken cancellationToken)
    {
        await _messageHubContext.DisposeAsync();
    }
    #endregion
}

My question is how do i return SignalRConnectionInfo in this case?

Thanks!

2

Answers


  1. If you want to negotiate an anonymous session, you can get it from the SignalRService, so you don’t need to pass UserId to your Negotiate function.

    [Function("Negotiate")]
    public static async Task<IActionResult> Negotiate(
        [HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req,
        FunctionContext context)
    {
        var signalRService = (SignalRService)context.InstanceServices.GetService(typeof(SignalRService));
        var connectionInfo = await signalRService.GetSignalRConnectionInfo();
    
        return new OkObjectResult(connectionInfo);
    }
    
    Login or Signup to reply.
  2. Use below code to return ConnectionInfo in Isolated Azure functions.

    • I have created a .NET 8.0 isolated Azure function.
    • UserId is optional parameter as mentioned in MSDOC and ConnectionInfo can be returned even without passing UserId.
    public class Function1
    {
        private readonly ILogger _logger;
    
        public Function1(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger("negotiate");
        }
    
        [Function("negotiate")]
        public HttpResponseData Negotiate(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req,
            [SignalRConnectionInfoInput(HubName = "HubValue", UserId ="")] MyConnectionInfo connectionInfo)
        {
            _logger.LogInformation($"SignalR Connection URL = '{connectionInfo.Url}'");
    
            var response = req.CreateResponse(HttpStatusCode.OK);
            response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
            response.WriteString($"Connection URL = '{connectionInfo.Url}'");
            
            return response;
        }
    }
    
    public class MyConnectionInfo
    {
        public string Url { get; set; }
    
        public string AccessToken { get; set; }
    }
    

    Console Response:

    Azure Functions Core Tools
    Core Tools Version:       4.0.5801 Commit hash: N/A +5ac2f09758b98257e728dd1b5576ce5ea9ef68ff (64-bit)
    Function Runtime Version: 4.34.1.22669
    
    [2024-06-12T12:45:03.702Z] Found C:UsersunameSourceReposFunctionApp18FunctionApp18.csproj. Using for user secrets file configuration.
    [2024-06-12T12:45:14.003Z] Azure Functions .NET Worker (PID: 12024) initialized in debug mode. Waiting for debugger to attach...
    [2024-06-12T12:45:14.144Z] Worker process started and initialized.
    
    Functions:
    
            negotiate: [POST] http://localhost:7065/api/negotiate
    
    For detailed output, run func with --verbose flag.
    [2024-06-12T12:45:19.095Z] Host lock lease acquired by instance ID '000000000000000000000000F72731CC'.
    [2024-06-12T12:45:20.088Z] Executing 'Functions.negotiate' (Reason='This function was programmatically called via the host APIs.', Id=c31883d3-4125-4cea-9c89-2c6456b76b26)
    [2024-06-12T12:45:20.918Z] SignalR Connection URL = 'https://functionapp17.service.signalr.net/client/?hub=hubvalue'
    [2024-06-12T12:45:21.022Z] Executed 'Functions.negotiate' (Succeeded, Id=c31883d3-4125-4cea-9c89-2c6456b76b26, Duration=968ms)
    

    Output:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search