SignalR client is not able to get Negotiate API response in "isolated worker model"

126 Views Asked by At

I have created a project where I implemented the "Negotiate" API to create the SignalR connection.

My client is in JavaScript having reference of "@microsoft/[email protected]".

On the Server side, I have implemented the "Negotiate" API as below.

I am using the following versions of the references:

Microsoft.AspNetCore.Http -> v 8.0 Microsoft.Azure.Functions.Worker -> v 1.21.0 Microsoft.Azure.Functions.Worker.Extensions.SignalRService -> v 1.13.0 Microsoft.Azure.Functions.Worker.Sdk -> v 1.17.0

using Microsoft.AspNetCore.Http;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace TestSignalRProj
{
    public class SignalRNegotiate
    {
        private readonly ILogger<SignalRNegotiate> _logger;

        public SignalRNegotiate(ILogger<SignalRNegotiate> logger)
        {
            _logger = logger;
        }

        [Function(nameof(Negotiate))]
        public static string Negotiate(
          [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
          [SignalRConnectionInfoInput(HubName = "submission")] string connectionInfo)
        {
            return connectionInfo;
        }
    }
}

When I tried to get a response from Postman, it did not return any value.

Kestral Logs

Postman Response

Reference URL I used to implement : Azure Functions SignalR Service input binding

2

There are 2 best solutions below

0
Hardik Patel On BEST ANSWER

I have addressed this matter by changing the return type from string to HttpResponseData class within the Microsoft.Azure.Functions.Worker.Http namespace. Additionally, I have updated the request object from HttpRequest to HttpRequestData, resulting in the following code structure. Reference : Azure SignalR Service

[Function(nameof(Negotiate))]
public static HttpResponseData Negotiate([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req, [SignalRConnectionInfoInput(HubName = "serverless")] string connectionInfo)
{
      var response = req.CreateResponse(HttpStatusCode.OK);
      response.Headers.Add("Content-Type", "application/json");
      response.WriteStringAsync(connectionInfo);
      return response;
}
0
Sampath On
  • The Negotiate is used for bi-directional communication between clients and serverless applications.

  • By using the SignalRConnectionInfo input binding, clients are provided with the necessary connection information, such as endpoint URL and access token, to establish secure connections to SignalR hubs.

  • The input binding allows developers to integrate authentication and authorization mechanisms into their Azure Functions. By including user ID claims or additional JWT tokens, developers can ensure that only authorized users can access specific SignalR hubs.

  • Use the SignalR output binding to send one or more messages using Azure SignalR Service.

  • Use the SignalR trigger binding to respond to messages sent from Azure SignalR Service.

  • From the image, I see you sending a message and unable to see the sent data. You need to add the SignalR trigger binding to the code.

Code:

[Function(nameof(OnClientMessage))]
    public static void OnClientMessage(
        [SignalRTrigger("Hub", "messages", "sendMessage", "content", ConnectionStringSetting = "SignalRConnection")]
        object invocationContext, string content, FunctionContext functionContext)
    {
        var logger = functionContext.GetLogger(nameof(OnClientMessage));
        logger.LogInformation("Received message from SignalR client. Content: {content}", content);
    }

    [Function(nameof(ReceiveMessage))]
    public static async Task<HttpResponseData> ReceiveMessage(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req,
        FunctionContext context)
    {
        var logger = context.GetLogger(nameof(ReceiveMessage));
        logger.LogInformation("Received a message via POST request.");

        using var reader = new StreamReader(req.Body);
        var requestBody = await reader.ReadToEndAsync();

        logger.LogInformation("Message content: {message}", requestBody);

        var response = req.CreateResponse(HttpStatusCode.OK);
        await response.WriteStringAsync("Message received successfully.");

        return response;
    }


enter image description here Output:

enter image description here