Skip to content

Commit 2192701

Browse files
authored
Merge pull request #268737 from Y-Sindo/javascriptdoc
Add samples for SignalR extensions of JavaScript V4 model
2 parents e39e3f2 + ab87779 commit 2192701

7 files changed

+382
-170
lines changed

articles/azure-functions/functions-bindings-signalr-service-input.md

Lines changed: 95 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ms.topic: reference
66
ms.devlang: csharp
77
# ms.devlang: csharp, java, javascript, python
88
ms.custom: devx-track-csharp, devx-track-extended-java, devx-track-js, devx-track-python
9-
ms.date: 01/13/2022
9+
ms.date: 03/12/2024
1010
ms.author: zityang
1111
zone_pivot_groups: programming-languages-set-functions-lang-workers
1212
---
@@ -38,35 +38,51 @@ The following example shows a [C# function](functions-dotnet-class-library.md) t
3838
[FunctionName("negotiate")]
3939
public static SignalRConnectionInfo Negotiate(
4040
[HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequest req,
41-
[SignalRConnectionInfo(HubName = "chat")]SignalRConnectionInfo connectionInfo)
41+
[SignalRConnectionInfo(HubName = "hubName1")]SignalRConnectionInfo connectionInfo)
4242
{
4343
return connectionInfo;
4444
}
4545
```
4646

4747
---
4848
::: zone-end
49-
::: zone pivot="programming-language-javascript,programming-language-python,programming-language-powershell"
5049

51-
The following example shows a SignalR connection info input binding in a *function.json* file and a function that uses the binding to return the connection information.
50+
::: zone pivot="programming-language-python,programming-language-powershell"
5251

53-
Here's binding data for the example in the *function.json* file:
54-
55-
```json
56-
{
57-
"type": "signalRConnectionInfo",
58-
"name": "connectionInfo",
59-
"hubName": "chat",
60-
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
61-
"direction": "in"
62-
}
63-
```
52+
[!INCLUDE [functions-bindings-signalr-input-function-json](../../includes/functions-bindings-signalr-input-function-json.md)]
6453

6554
::: zone-end
6655
::: zone pivot="programming-language-javascript"
6756

6857
Here's the JavaScript code:
6958

59+
# [Model v4](#tab/nodejs-v4)
60+
61+
```javascript
62+
const { app, input } = require('@azure/functions');
63+
64+
const inputSignalR = input.generic({
65+
type: 'signalRConnectionInfo',
66+
name: 'connectionInfo',
67+
hubName: 'hubName1',
68+
connectionStringSetting: 'AzureSignalRConnectionString',
69+
});
70+
71+
app.post('negotiate', {
72+
authLevel: 'function',
73+
handler: (request, context) => {
74+
return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
75+
},
76+
route: 'negotiate',
77+
extraInputs: [inputSignalR],
78+
});
79+
80+
```
81+
82+
# [Model v3](#tab/nodejs-v3)
83+
84+
[!INCLUDE [functions-bindings-signalr-input-function-json](../../includes/functions-bindings-signalr-input-function-json.md)]
85+
7086
```javascript
7187
module.exports = async function (context, req, connectionInfo) {
7288
context.res.body = connectionInfo;
@@ -109,7 +125,7 @@ public SignalRConnectionInfo negotiate(
109125
authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> req,
110126
@SignalRConnectionInfoInput(
111127
name = "connectionInfo",
112-
hubName = "chat") SignalRConnectionInfo connectionInfo) {
128+
HubName = "hubName1") SignalRConnectionInfo connectionInfo) {
113129
return connectionInfo;
114130
}
115131
```
@@ -124,14 +140,16 @@ When an authenticated client triggers the function, you can add a user ID claim
124140

125141
App Service authentication sets HTTP headers named `x-ms-client-principal-id` and `x-ms-client-principal-name` that contain the authenticated user's client principal ID and name, respectively.
126142

143+
You can set the `UserId` property of the binding to the value from either header using a [binding expression](#binding-expressions-for-http-trigger): `{headers.x-ms-client-principal-id}` or `{headers.x-ms-client-principal-name}`.
144+
127145
::: zone pivot="programming-language-csharp"
128146

129147
# [Isolated worker model](#tab/isolated-process)
130148

131149
```cs
132150
[Function("Negotiate")]
133151
public static string Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req,
134-
[SignalRConnectionInfoInput(HubName = "serverless", UserId = "{headers.x-ms-client-principal-id}")] string connectionInfo)
152+
[SignalRConnectionInfoInput(HubName = "hubName1", UserId = "{headers.x-ms-client-principal-id}")] string connectionInfo)
135153
{
136154
// The serialization of the connection info object is done by the framework. It should be camel case. The SignalR client respects the camel case response only.
137155
return connectionInfo;
@@ -140,14 +158,13 @@ public static string Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpR
140158

141159
# [In-process model](#tab/in-process)
142160

143-
You can set the `UserId` property of the binding to the value from either header using a [binding expression](#binding-expressions-for-http-trigger): `{headers.x-ms-client-principal-id}` or `{headers.x-ms-client-principal-name}`.
144161

145162
```cs
146163
[FunctionName("negotiate")]
147164
public static SignalRConnectionInfo Negotiate(
148165
[HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequest req,
149166
[SignalRConnectionInfo
150-
(HubName = "chat", UserId = "{headers.x-ms-client-principal-id}")]
167+
(HubName = "hubName1", UserId = "{headers.x-ms-client-principal-id}")]
151168
SignalRConnectionInfo connectionInfo)
152169
{
153170
// connectionInfo contains an access key token with a name identifier claim set to the authenticated user
@@ -168,23 +185,21 @@ public SignalRConnectionInfo negotiate(
168185
methods = { HttpMethod.POST, HttpMethod.GET },
169186
authLevel = AuthorizationLevel.ANONYMOUS)
170187
HttpRequestMessage<Optional<String>> req,
171-
@SignalRConnectionInfoInput(name = "connectionInfo", hubName = "simplechat", userId = "{headers.x-ms-signalr-userid}") SignalRConnectionInfo connectionInfo) {
188+
@SignalRConnectionInfoInput(name = "connectionInfo", hubName = "hubName1", userId = "{headers.x-ms-signalr-userid}") SignalRConnectionInfo connectionInfo) {
172189
return connectionInfo;
173190
}
174191
```
175192
::: zone-end
176193

177-
::: zone pivot="programming-language-javascript,programming-language-python,programming-language-powershell"
178-
179-
You can set the `userId` property of the binding to the value from either header using a [binding expression](#binding-expressions-for-http-trigger): `{headers.x-ms-client-principal-id}` or `{headers.x-ms-client-principal-name}`.
194+
::: zone pivot="programming-language-python,programming-language-powershell"
180195

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

183198
```json
184199
{
185200
"type": "signalRConnectionInfo",
186201
"name": "connectionInfo",
187-
"hubName": "chat",
202+
"hubName": "hubName1",
188203
"userId": "{headers.x-ms-client-principal-id}",
189204
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
190205
"direction": "in"
@@ -195,14 +210,50 @@ Here's binding data in the *function.json* file:
195210
::: zone pivot="programming-language-javascript"
196211
Here's the JavaScript code:
197212

213+
# [Model v4](#tab/nodejs-v4)
214+
```javascript
215+
const { app, input } = require('@azure/functions');
216+
217+
const inputSignalR = input.generic({
218+
type: 'signalRConnectionInfo',
219+
name: 'connectionInfo',
220+
hubName: 'hubName1',
221+
connectionStringSetting: 'AzureSignalRConnectionString',
222+
userId: '{headers.x-ms-client-principal-id}',
223+
});
224+
225+
app.post('negotiate', {
226+
authLevel: 'function',
227+
handler: (request, context) => {
228+
return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
229+
},
230+
route: 'negotiate',
231+
extraInputs: [inputSignalR],
232+
});
233+
```
234+
235+
# [Model v3](#tab/nodejs-v3)
236+
237+
Here's binding data in the *function.json* file:
238+
239+
```json
240+
{
241+
"type": "signalRConnectionInfo",
242+
"name": "connectionInfo",
243+
"hubName": "hubName1",
244+
"userId": "{headers.x-ms-client-principal-id}",
245+
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
246+
"direction": "in"
247+
}
248+
```
249+
198250
```javascript
199251
module.exports = async function (context, req, connectionInfo) {
200252
// connectionInfo contains an access key token with a name identifier
201253
// claim set to the authenticated user
202254
context.res.body = connectionInfo;
203255
};
204256
```
205-
206257
::: zone-end
207258
::: zone pivot="programming-language-powershell"
208259

@@ -228,8 +279,6 @@ def main(req: func.HttpRequest, connectionInfo: str) -> func.HttpResponse:
228279
::: zone-end
229280
::: zone pivot="programming-language-java"
230281

231-
You can set the `userId` property of the binding to the value from either header using a [binding expression](#binding-expressions-for-http-trigger): `{headers.x-ms-client-principal-id}` or `{headers.x-ms-client-principal-name}`.
232-
233282
```java
234283
@FunctionName("negotiate")
235284
public SignalRConnectionInfo negotiate(
@@ -239,7 +288,7 @@ public SignalRConnectionInfo negotiate(
239288
authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> req,
240289
@SignalRConnectionInfoInput(
241290
name = "connectionInfo",
242-
hubName = "chat",
291+
HubName = "hubName1",
243292
userId = "{headers.x-ms-client-principal-id}") SignalRConnectionInfo connectionInfo) {
244293
return connectionInfo;
245294
}
@@ -281,6 +330,22 @@ The following table explains the properties of the `SignalRConnectionInfo` attri
281330
::: zone-end
282331
::: zone pivot="programming-language-java"
283332

333+
## Annotations
334+
335+
The following table explains the supported settings for the `SignalRConnectionInfoInput` annotation.
336+
337+
|Setting | Description|
338+
|---------|--------|
339+
|**name**| Variable name used in function code for connection info object. |
340+
|**hubName**| Required. The hub name. |
341+
|**connectionStringSetting**| The name of the app setting that contains the SignalR Service connection string, which defaults to `AzureSignalRConnectionString`. |
342+
|**userId**| Optional. The user identifier of a SignalR connection. You can use a [binding expression](#binding-expressions-for-http-trigger) to bind the value to an HTTP request header or query. |
343+
|**idToken**| Optional. A JWT token whose claims will be added to the user claims. It should be used together with **claimTypeList**. You can use a [binding expression](#binding-expressions-for-http-trigger) to bind the value to an HTTP request header or query. |
344+
|**claimTypeList**| Optional. A list of claim types, which filter the claims in **idToken** . |
345+
346+
::: zone-end
347+
348+
::: zone pivot="programming-language-javascript"
284349

285350
## Annotations
286351

@@ -296,7 +361,8 @@ The following table explains the supported settings for the `SignalRConnectionIn
296361
|**claimTypeList**| Optional. A list of claim types, which filter the claims in **idToken** . |
297362

298363
::: zone-end
299-
::: zone pivot="programming-language-javascript,programming-language-powershell,programming-language-python"
364+
365+
::: zone pivot="programming-language-powershell,programming-language-python"
300366
## Configuration
301367

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

0 commit comments

Comments
 (0)