SignalR Service output binding for Azure Functions

Use the SignalR output binding to send one or more messages using Azure SignalR Service. You can broadcast a message to:

  • All connected clients
  • Connected clients authenticated to a specific user

The output binding also allows you to manage groups.

For information on setup and configuration details, see the overview.

Example

A C# function can be created using one of the following C# modes:

  • In-process class library: compiled C# function that runs in the same process as the Functions runtime.
  • Isolated worker process class library: compiled C# function that runs in a worker process that is isolated from the runtime. Isolated worker process is required to support C# functions running on non-LTS versions .NET and the .NET Framework.
  • C# script: used primarily when creating C# functions in the Azure portal.

Broadcast to all clients

The following example shows a function that sends a message using the output binding to all connected clients. The target is the name of the method to be invoked on each client. The Arguments property is an array of zero or more objects to be passed to the client method.

[FunctionName("SendMessage")]
public static Task SendMessage(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post")]object message,
    [SignalR(HubName = "chat")]IAsyncCollector<SignalRMessage> signalRMessages)
{
    return signalRMessages.AddAsync(
        new SignalRMessage
        {
            Target = "newMessage",
            Arguments = new [] { message }
        });
}

Broadcast to all clients

Here's binding data in the function.json file:

Example function.json:

{
  "type": "signalR",
  "name": "signalRMessages",
  "hubName": "<hub_name>",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}

Here's the JavaScript code:

module.exports = async function (context, req) {
    context.bindings.signalRMessages = [{
        "target": "newMessage",
        "arguments": [ req.body ]
    }];
};

Complete PowerShell examples are pending.

Here's the Python code:

def main(req: func.HttpRequest, outMessage: func.Out[str]) -> func.HttpResponse:
    message = req.get_json()
    outMessage.set(json.dumps({
        'target': 'newMessage',
        'arguments': [ message ]
    }))

Broadcast to all clients

@FunctionName("sendMessage")
@SignalROutput(name = "$return", hubName = "chat")
public SignalRMessage sendMessage(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req) {

    SignalRMessage message = new SignalRMessage();
    message.target = "newMessage";
    message.arguments.add(req.getBody());
    return message;
}

Send to a user

You can send a message only to connections that have been authenticated to a user by setting the user ID in the SignalR message.

[FunctionName("SendMessage")]
public static Task SendMessage(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post")]object message,
    [SignalR(HubName = "chat")]IAsyncCollector<SignalRMessage> signalRMessages)
{
    return signalRMessages.AddAsync(
        new SignalRMessage
        {
            // the message will only be sent to this user ID
            UserId = "userId1",
            Target = "newMessage",
            Arguments = new [] { message }
        });
}

Send to a user

You can send a message only to connections that have been authenticated to a user by setting the user ID in the SignalR message.

Example function.json:

{
  "type": "signalR",
  "name": "outRMessages",
  "hubName": "<hub_name>",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}

Here's the JavaScript code:

module.exports = async function (context, req) {
    context.bindings.signalRMessages  = [{
        // message will only be sent to this user ID
        "userId": "userId1",
        "target": "newMessage",
        "arguments": [ req.body ]
    }];
};

Complete PowerShell examples are pending.

Here's the Python code:

def main(req: func.HttpRequest, outMessages: func.Out[str]) -> func.HttpResponse:
    message = req.get_json()
    outMessage.set(json.dumps({
        #message will only be sent to this user ID
        'userId': 'userId1',
        'target': 'newMessage',
        'arguments': [ message ]
    }))

Send to a user

You can send a message only to connections that have been authenticated to a user by setting the user ID in the SignalR message.

@FunctionName("sendMessage")
@SignalROutput(name = "$return", hubName = "chat")
public SignalRMessage sendMessage(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req) {

    SignalRMessage message = new SignalRMessage();
    message.userId = "userId1";
    message.target = "newMessage";
    message.arguments.add(req.getBody());
    return message;
}

Send to a group

You can send a message only to connections that have been added to a group by setting the group name in the SignalR message.

[FunctionName("SendMessage")]
public static Task SendMessage(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post")]object message,
    [SignalR(HubName = "chat")]IAsyncCollector<SignalRMessage> signalRMessages)
{
    return signalRMessages.AddAsync(
        new SignalRMessage
        {
            // the message will be sent to the group with this name
            GroupName = "myGroup",
            Target = "newMessage",
            Arguments = new [] { message }
        });
}

Send to a group

You can send a message only to connections that have been added to a group by setting the group name in the SignalR message.

Example function.json:

{
  "type": "signalR",
  "name": "signalRMessages",
  "hubName": "<hub_name>",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}

Here's the JavaScript code:

module.exports = async function (context, req) {
    context.bindings.signalRMessages = [{
        // message will only be sent to this group
        "groupName": "myGroup",
        "target": "newMessage",
        "arguments": [ req.body ]
    }];
};

Complete PowerShell examples are pending.

Here's the Python code:

def main(req: func.HttpRequest, outMessage: func.Out[str]) -> func.HttpResponse:
    message = req.get_json()
    outMessage.set(json.dumps({
        #message will only be sent to this group
        'groupName': 'myGroup',
        'target': 'newMessage',
        'arguments': [ message ]
    }))

Send to a group

You can send a message only to connections that have been added to a group by setting the group name in the SignalR message.

@FunctionName("sendMessage")
@SignalROutput(name = "$return", hubName = "chat")
public SignalRMessage sendMessage(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req) {

    SignalRMessage message = new SignalRMessage();
    message.groupName = "myGroup";
    message.target = "newMessage";
    message.arguments.add(req.getBody());
    return message;
}

Group management

SignalR Service allows users or connections to be added to groups. Messages can then be sent to a group. You can use the SignalR output binding to manage groups.

Specify GroupAction to add or remove a member. The following example adds a user to a group.

[FunctionName("addToGroup")]
public static Task AddToGroup(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post")]HttpRequest req,
    ClaimsPrincipal claimsPrincipal,
    [SignalR(HubName = "chat")]
        IAsyncCollector<SignalRGroupAction> signalRGroupActions)
{
    var userIdClaim = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier);
    return signalRGroupActions.AddAsync(
        new SignalRGroupAction
        {
            UserId = userIdClaim.Value,
            GroupName = "myGroup",
            Action = GroupAction.Add
        });
}

Note

In order to get the ClaimsPrincipal correctly bound, you must have configured the authentication settings in Azure Functions.

Group management

SignalR Service allows users or connections to be added to groups. Messages can then be sent to a group. You can use the SignalR output binding to manage groups.

Example function.json that defines the output binding:

{
    "type": "signalR",
    "name": "signalRGroupActions",
    "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
    "hubName": "chat",
    "direction": "out"
}

The following example adds a user to a group.

module.exports = async function (context, req) {
  context.bindings.signalRGroupActions = [{
    "userId": req.query.userId,
    "groupName": "myGroup",
    "action": "add"
  }];
};

The following example removes a user from a group.

module.exports = async function (context, req) {
  context.bindings.signalRGroupActions = [{
    "userId": req.query.userId,
    "groupName": "myGroup",
    "action": "remove"
  }];
};

Complete PowerShell examples are pending.

The following example adds a user to a group.

def main(req: func.HttpRequest, action: func.Out[str]) -> func.HttpResponse:
    action.set(json.dumps({
        'userId': 'userId1',
        'groupName': 'myGroup',
        'action': 'add'
    }))

The following example removes a user from a group.

def main(req: func.HttpRequest, action: func.Out[str]) -> func.HttpResponse:
    action.set(json.dumps({
        'userId': 'userId1',
        'groupName': 'myGroup',
        'action': 'remove'
    }))

Group management

SignalR Service allows users or connections to be added to groups. Messages can then be sent to a group. You can use the SignalR output binding to manage groups.

The following example adds a user to a group.

@FunctionName("addToGroup")
@SignalROutput(name = "$return", hubName = "chat")
public SignalRGroupAction addToGroup(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req,
        @BindingName("userId") String userId) {

    SignalRGroupAction groupAction = new SignalRGroupAction();
    groupAction.action = "add";
    groupAction.userId = userId;
    groupAction.groupName = "myGroup";
    return action;
}

The following example removes a user from a group.

@FunctionName("removeFromGroup")
@SignalROutput(name = "$return", hubName = "chat")
public SignalRGroupAction removeFromGroup(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req,
        @BindingName("userId") String userId) {

    SignalRGroupAction groupAction = new SignalRGroupAction();
    groupAction.action = "remove";
    groupAction.userId = userId;
    groupAction.groupName = "myGroup";
    return action;
}

Attributes

Both in-process and isolated worker process C# libraries use attribute to define the function. C# script instead uses a function.json configuration file.

The following table explains the properties of the SignalR output attribute.

Attribute property Description
HubName This value must be set to the name of the SignalR hub for which the connection information is generated.
ConnectionStringSetting The name of the app setting that contains the SignalR Service connection string, which defaults to AzureSignalRConnectionString.

Annotations

The following table explains the supported settings for the SignalROutput annotation.

Setting Description
name Variable name used in function code for connection info object.
hubName This value must be set to the name of the SignalR hub for which the connection information is generated.
connectionStringSetting The name of the app setting that contains the SignalR Service connection string, which defaults to AzureSignalRConnectionString.

Configuration

The following table explains the binding configuration properties that you set in the function.json file.

function.json property Description
type Must be set to signalR.
direction Must be set to out.
name Variable name used in function code for connection info object.
hubName This value must be set to the name of the SignalR hub for which the connection information is generated.
connectionStringSetting The name of the app setting that contains the SignalR Service connection string, which defaults to AzureSignalRConnectionString.

When you're developing locally, add your application settings in the local.settings.json file in the Values collection.

Next steps