Use the SignalR trigger binding to respond to messages sent from Azure SignalR Service. When function is triggered, messages passed to the function is parsed as a json object.
In SignalR Service serverless mode, SignalR Service uses the Upstream feature to send messages from client to Function App. And Function App uses SignalR Service trigger binding to handle these messages. The general architecture is shown below:
For information on setup and configuration details, see the overview.
ExampleYou can create a C# function by using one of the following C# modes:
The following sample shows a C# function that receives a message event from clients and logs the message content.
[Function(nameof(OnClientMessage))]
public static void OnClientMessage(
[SignalRTrigger("Hub", "messages", "sendMessage", "content", ConnectionStringSetting = "SignalRConnection")]
SignalRInvocationContext invocationContext, string content, FunctionContext functionContext)
{
var logger = functionContext.GetLogger(nameof(OnClientMessage));
logger.LogInformation("Connection {connectionId} sent a message. Message content: {content}", invocationContext.ConnectionId, content);
}
Important
Class based model of SignalR Service bindings in C# isolated worker doesn't optimize how you write SignalR triggers due to the limitation of C# worker model. For more information about class based model, see Class based model.
SignalR Service trigger binding for C# in-process model has two programming models. Class based model and traditional model. Class based model provides a consistent SignalR server-side programming experience. Traditional model provides more flexibility and is similar to other function bindings.
With class-based modelSee Class based model for details.
public class HubName1 : ServerlessHub
{
[FunctionName("SignalRTest")]
public Task SendMessage([SignalRTrigger]InvocationContext invocationContext, string message, ILogger logger)
{
logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
}
}
With a traditional model
Traditional model obeys the convention of Azure Function developed by C#. If you're not familiar with it, you can learn from documents.
[FunctionName("SignalRTest")]
public static Task Run([SignalRTrigger("SignalRTest", "messages", "SendMessage", parameterNames: new string[] {"message"})]InvocationContext invocationContext, string message, ILogger logger)
{
logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
}
Because it can be hard to use ParameterNames
in the trigger, the following example shows you how to use the SignalRParameter
attribute to define the message
attribute.
[FunctionName("SignalRTest")]
public static Task Run([SignalRTrigger("SignalRTest", "messages", "SendMessage")]InvocationContext invocationContext, [SignalRParameter]string message, ILogger logger)
{
logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
}
SignalR trigger isn't currently supported for Java.
Here's binding data in the function.json file:
{
"type": "signalRTrigger",
"name": "invocation",
"hubName": "hubName1",
"category": "messages",
"event": "SendMessage",
"parameterNames": [
"message"
],
"direction": "in"
}
app.generic("function1",
{
trigger: { "type": "signalRTrigger", "name": "invocation", "direction": "in", "hubName": "hubName1", "event": "SendMessage", "category": "messages" },
handler: (triggerInput, context) => {
context.log(`Receive ${triggerInput.Arguments[0]} from ${triggerInput.ConnectionId}.`)
}
})
Here's binding data in the function.json file:
{
"type": "signalRTrigger",
"name": "invocation",
"hubName": "hubName1",
"category": "messages",
"event": "SendMessage",
"parameterNames": [
"message"
],
"direction": "in"
}
Here's the JavaScript code:
module.exports = function (context, invocation) {
context.log(`Receive ${context.bindingData.message} from ${invocation.ConnectionId}.`)
};
Complete PowerShell examples are pending.
Here's the Python code:
import logging
import json
import azure.functions as func
def main(invocation) -> None:
invocation_json = json.loads(invocation)
logging.info("Receive {0} from {1}".format(invocation_json['Arguments'][0], invocation_json['ConnectionId']))
Attributes
Both in-process and isolated worker process C# libraries use the SignalRTrigger
attribute to define the function. C# script instead uses a function.json configuration file.
The following table explains the properties of the SignalRTrigger
attribute.
AzureSignalRConnectionString
.
The following table explains the properties of the SignalRTrigger
attribute.
AzureSignalRConnectionString
. Annotations
There isn't currently a supported Java annotation for a SignalR trigger.
ConfigurationThe following table explains the binding configuration properties that you set in the function.json file.
function.json property Description type Must be set toSignalRTrigger
. direction Must be set to in
. name Variable name used in function code for trigger invocation context object. hubName This value must be set to the name of the SignalR hub for the function to be triggered. category This value must be set as the category of messages for the function to be triggered. The category can be one of the following values:
AzureSignalRConnectionString
.
See the Example section for complete examples.
Usage Managed identity-based connectionsFor optimal security, your function app should use managed identities when connecting to the Azure SignalR service instead of using a connection string, which contains a shared secret key. For more information, see Authorize requests to Azure SignalR Service resources with Microsoft Entra managed identities.
PayloadsThe trigger input type is declared as either InvocationContext
or a custom type. If you choose InvocationContext
, you get full access to the request content. For a custom type, the runtime tries to parse the JSON request body to set the object properties.
InvocationContext
contains all the content in the message sent from a SignalR service, which includes the following properties:
ParameterNames
The property ParameterNames
in SignalRTrigger
lets you bind arguments of invocation messages to the parameters of functions. You can use the name you defined as part of binding expressions in other binding or as parameters in your code. That gives you a more convenient way to access arguments of InvocationContext
.
Say you have a JavaScript SignalR client trying to invoke method broadcast
in Azure Function with two arguments message1
, message2
.
await connection.invoke("broadcast", message1, message2);
After you set parameterNames
, the names you defined correspond to the arguments sent on the client side.
[SignalRTrigger(parameterNames: new string[] {"arg1, arg2"})]
Then, the arg1
contains the content of message1
, and arg2
contains the content of message2
.
ParameterNames
considerations
For the parameter binding, the order matters. If you're using ParameterNames
, the order in ParameterNames
matches the order of the arguments you invoke in the client. If you're using attribute [SignalRParameter]
in C#, the order of arguments in Azure Function methods matches the order of arguments in clients.
ParameterNames
and attribute [SignalRParameter]
cannot be used at the same time, or you'll get an exception.
SignalR Service needs a URL to access Function App when you're using SignalR Service trigger binding. The URL should be configured in Upstream Settings on the SignalR Service side.
When using SignalR Service trigger, the URL can be simple and formatted as follows:
<Function_App_URL>/runtime/webhooks/signalr?code=<API_KEY>
The Function_App_URL
can be found on Function App's Overview page and the API_KEY
is generated by Azure Function. You can get the API_KEY
from signalr_extension
in the App keys blade of Function App.
If you want to use more than one Function App together with one SignalR Service, upstream can also support complex routing rules. Find more details at Upstream settings.
Step-by-step sampleYou can follow the sample in GitHub to deploy a chat room on Function App with SignalR Service trigger binding and upstream feature: Bidirectional chat room sample
Next stepsRetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4