Skip to content

Latest commit

 

History

History
276 lines (190 loc) · 14.4 KB

functions-bindings-signalr-service-trigger.md

File metadata and controls

276 lines (190 loc) · 14.4 KB
titledescriptionauthorms.topicms.devlangms.customms.datems.authorzone_pivot_groups
Azure Functions SignalR Service trigger binding
Learn to handle SignalR Service messages from Azure Functions.
Y-Sindo
reference
csharp
devx-track-csharp, devx-track-extended-java, devx-track-js, devx-track-python
04/02/2024
zityang
programming-languages-set-functions-lang-workers

SignalR Service trigger binding for Azure Functions

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:

:::image type="content" source="media/functions-bindings-signalr-service/signalr-trigger.png" alt-text="SignalR Trigger Architecture":::

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

Example

::: zone pivot="programming-language-csharp"

[!INCLUDE functions-bindings-csharp-intro-with-csx]

[!INCLUDE functions-in-process-model-retirement-note]

The following sample shows a C# function that receives a message event from clients and logs the message content.

:::code language="csharp" source="~/azure-functions-dotnet-worker/samples/Extensions/SignalR/SignalRTriggerFunctions.cs" id="snippet_on_message":::

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 model

See Class based model for details.

publicclassHubName1:ServerlessHub{[FunctionName("SignalRTest")]publicTaskSendMessage([SignalRTrigger]InvocationContextinvocationContext,stringmessage,ILoggerlogger){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")]publicstaticTaskRun([SignalRTrigger("SignalRTest","messages","SendMessage",parameterNames:newstring[]{"message"})]InvocationContextinvocationContext,stringmessage,ILoggerlogger){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")]publicstaticTaskRun([SignalRTrigger("SignalRTest","messages","SendMessage")]InvocationContextinvocationContext,[SignalRParameter]stringmessage,ILoggerlogger){logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");}

::: zone-end

::: zone pivot="programming-language-java" SignalR trigger isn't currently supported for Java. ::: zone-end

::: zone pivot="programming-language-python,programming-language-powershell"

[!INCLUDE functions-bindings-signalr-trigger-function-json]

::: zone-end ::: zone pivot="programming-language-javascript"

app.generic("function1",{trigger: {"type": "signalRTrigger","name": "invocation","direction": "in","hubName": "hubName1","event": "SendMessage","category": "messages"},handler: (triggerInput,context)=>{context.log(`Receive ${context.Arguments[0]} from ${triggerInput.ConnectionId}.`)}})

[!INCLUDE functions-bindings-signalr-trigger-function-json]

Here's the JavaScript code:

module.exports=function(context,invocation){context.log(`Receive ${context.bindingData.message} from ${invocation.ConnectionId}.`)};

::: zone-end ::: zone pivot="programming-language-powershell"

Complete PowerShell examples are pending. ::: zone-end ::: zone pivot="programming-language-python"

Here's the Python code:

importloggingimportjsonimportazure.functionsasfuncdefmain(invocation) ->None: invocation_json=json.loads(invocation) logging.info("Receive {0} from {1}".format(invocation_json['Arguments'][0], invocation_json['ConnectionId']))

::: zone-end

::: zone pivot="programming-language-csharp"

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.

Attribute propertyDescription
HubNameThis value must be set to the name of the SignalR hub for the function to be triggered.
CategoryThis value must be set as the category of messages for the function to be triggered. The category can be one of the following values:
  • connections: Including connected and disconnected events
  • messages: Including all other events except those in connections category
EventThis value must be set as the event of messages for the function to be triggered. For messages category, event is the target in invocation message that clients send. For connections category, only connected and disconnected is used.
ParameterNames(Optional) A list of names that binds to the parameters.
ConnectionStringSettingThe name of the app setting or settings collection that contains the SignalR Service connection string, which defaults to AzureSignalRConnectionString.

The following table explains the properties of the SignalRTrigger attribute.

Attribute propertyDescription
HubNameThis value must be set to the name of the SignalR hub for the function to be triggered.
CategoryThis value must be set as the category of messages for the function to be triggered. The category can be one of the following values:
  • connections: Including connected and disconnected events
  • messages: Including all other events except those in connections category
EventThis value must be set as the event of messages for the function to be triggered. For messages category, event is the target in invocation message that clients send. For connections category, only connected and disconnected is used.
ParameterNames(Optional) A list of names that binds to the parameters.
ConnectionStringSettingThe name of the app setting or settings collection that contains the SignalR Service connection string, which defaults to AzureSignalRConnectionString.

::: zone-end ::: zone pivot="programming-language-java"

Annotations

There isn't currently a supported Java annotation for a SignalR trigger. ::: zone-end ::: zone pivot="programming-language-powershell,programming-language-python"

Configuration

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

function.json propertyDescription
typeMust be set to SignalRTrigger.
directionMust be set to in.
nameVariable name used in function code for trigger invocation context object.
hubNameThis value must be set to the name of the SignalR hub for the function to be triggered.
categoryThis value must be set as the category of messages for the function to be triggered. The category can be one of the following values:
  • connections: Including connected and disconnected events
  • messages: Including all other events except those in connections category
eventThis value must be set as the event of messages for the function to be triggered. For messages category, event is the target in invocation message that clients send. For connections category, only connected and disconnected is used.
parameterNames(Optional) A list of names that binds to the parameters.
connectionStringSettingThe name of the app setting or settings collection that contains the SignalR Service connection string, which defaults to AzureSignalRConnectionString.

::: zone-end

See the Example section for complete examples.

Usage

Managed identity-based connections

[!INCLUDE functions-azure-signalr-authorization-note]

Payloads

The 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

InvocationContext contains all the content in the message sent from a SignalR service, which includes the following properties:

PropertyDescription
ArgumentsAvailable for messages category. Contains arguments in invocation message
ErrorAvailable for disconnected event. It can be Empty if the connection closed with no error, or it contains the error messages.
HubThe hub name that the message belongs to.
CategoryThe category of the message.
EventThe event of the message.
ConnectionIdThe connection ID of the client that sends the message.
UserIdThe user identity of the client that sends the message.
HeadersThe headers of the request.
QueryThe query of the request when clients connect to the service.
ClaimsThe claims of the client.

Using 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.

awaitconnection.invoke("broadcast",message1,message2);

After you set parameterNames, the names you defined correspond to the arguments sent on the client side.

[SignalRTrigger(parameterNames:newstring[]{"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 integration

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.

:::image type="content" source="../azure-signalr/media/concept-upstream/upstream-portal.png" alt-text="Upstream Portal":::

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. :::image type="content" source="media/functions-bindings-signalr-service/signalr-keys.png" alt-text="API key":::

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 sample

You 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 steps

close