5

I am building an application based on serverless architecture. The part, where i am stuck includes: SPA Web UI, C# .Net 5.0 isolated process Function (dotnet-isolated), Azure SignalR Service (serverless mode).

There is a lot of documentation and examples how to build different real-time serverless apps using the the same stack i mentioned, but with .Net 3.1 Functions. And almost none information about SignalR output bindings for .Net 5.0 isolated process Functions triggered by SignalR.

The only helpful documentation out there is the following: C# isolated process: https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide SignalR Extension: https://github.com/Azure/azure-functions-dotnet-worker/tree/main/samples/Extensions/SignalR

So, basics are covered there. But, there is no information about some advanced SignalR output bindings, that will help to build some more functions like: Add User To Group, Remove User From Group. Etc.

So far i was able to build and run: Negotiate, SendMessage (to all, user or group) , Connected, Disconnected

But i am struggling with AddToGroup part... Here is my code:

        [Function(nameof(AddToGroup))]
        [SignalROutput(HubName = "WebUINotifications", ConnectionStringSetting = "AzureSignalRConnectionString")]
        public static OutputObject AddToGroup(
            [SignalRTrigger("WebUINotifications", "messages", "AddToGroup")] string item,
            FunctionContext context)
        {
            var logger = context.GetLogger("AddToGroup");

            var signalrGroup = JsonSerializer.Deserialize<SignalRGroup>(item);
            var userId = signalrGroup.UserId;
            var groupName = signalrGroup.Arguments[0];

            logger.LogInformation($"UserId: {userId}");
            logger.LogInformation($"Group Name: {groupName}");

            return new OutputObject()
            {
                UserId = userId,
                GroupName = groupName,
            };
        }

After configuring UpStream settings for SignalR Service in Azure, my function gets triggered successfully by javascript from Web UI

this.connection.invoke('AddToGroup', 'TestGroup');

But i get the error, which is not surprising at all, because it is not clear how exactly to bind:

System.Private.CoreLib: Exception while executing function: Functions.AddToGroup. Microsoft.Azure.WebJobs.Extensions.SignalRService: Unable to convert JObject to valid output binding type, check parameters.

What am i missing? Where to find documentation?

Thanks guys!

  • I'm facing the same problem. I have looked everywhere and the documentation seems to just ignore this. All the code examples are outdated and none of the questions about this ever get an answer. I think SignalR support in .net 5 azure functions is currently missing. – MetaFight Jul 09 '21 at 18:45
  • George how have you implemented the **SendMessage (to all, user or group)** ? I seem to hit a wall even on this. – Konstantine Aug 31 '21 at 13:16

2 Answers2

1

I have made a sample project to show what data types the SignalR extension expects. And here is a link to a github discussion for more information and context.

Here is a snippet of the data type for group actions. Be aware that the group name is required, even when using the action removeAll due to an oversight in an update to the SignalR code.

public class SignalRGroupAction
{
    public string connectionId { get; set; }

    public string userId { get; set; }

    /// <summary>
    /// Required
    /// </summary>
    public string groupName { get; set; }

    /// <summary>
    /// Required. Must be one of "add", "remove", "removeAll"
    /// </summary>
    public string action { get; set; }
}
log234
  • 93
  • 1
  • 6
  • I coincidentally setup a project similar to yours but unable to receive an event on the client side when upstream's "connected" event raises. Can you please tell me what the issue is in this stackoverflow question: https://stackoverflow.com/questions/74754573/unable-to-send-a-message-to-the-connected-user-when-signalr-trigger-raises-in-up – Arash Dec 12 '22 at 17:02
-1

This is just a guess as I am also struggling to find any documentation.

In previous verions a SignalRMessage was returned:

https://github.com/Azure/azure-functions-signalrservice-extension/blob/e191a3011099049ceb6a3580a54ae2ec8dbbc2b6/src/SignalRServiceExtension/Bindings/SignalRMessage.cs

 /// <summary>
/// Class that contains parameters needed for sending messages.
/// There are three kinds of scope to send, and if more than one
/// scopes are set, it will be resolved by the following order:
///     1. ConnectionId
///     2. UserId
///     3. GroupName
/// </summary>
[JsonObject]
public class SignalRMessage
{
    [JsonProperty("connectionId")]
    public string ConnectionId { get; set; }

    [JsonProperty("userId")]
    public string UserId { get; set; }

    [JsonProperty("groupName")]
    public string GroupName { get; set; }

    [JsonProperty("target"), JsonRequired]
    public string Target { get; set; }

    [JsonProperty("arguments"), JsonRequired]
    public object[] Arguments { get; set; }

    [JsonProperty("endpoints")]
    public ServiceEndpoint[] Endpoints { get; set; }
}

As you can see from the comments, the type of message is resolved by checking which property is set.

In your code, I would remove the 'UserId' property and also add the Json serialization attributes.

Apologies if this doesn't help.

Lee Smith
  • 6,339
  • 6
  • 27
  • 34