How to do signal R connections in Azure Functions with v4 nodejs?

242 Views Asked by At

I've been building a new function app on the nodejs v4 model. I'm struggling to get signal R negotiate and posts to work however, and documentation seems to be non existent as of yet. Has any one done this successfully?

2

There are 2 best solutions below

1
Pravallika KV On

Run the below commands in the terminal to create SignalR Azure function:

func init --worker-runtime Javascript
func new(select the trigger)
func new -n index -t HttpTrigger
func new -n broadcast -t TimerTrigger

enter image description here

enter image description here enter image description here

local.settings.json:

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "AzureSignalRConnectionString":"<your_SignalR_conn_string>"
  }
}

Response:

  • Run func host start in the terminal :

enter image description here

enter image description here

Reference:

You can refer MSDOC1 and MSDOC2 for clear steps on how to create SingalR triggered Azure function.

0
Aiden Dipple On

I had the same issue with Azure Function version 4 programming model binding (see How to get Angular SignalR hub connection to Azure Typescript Function with version 4.0 programming model)

Binding for the signalRTrigger Azure Function:

/* 

V3 SYNTAX BEING CONVERTED TO V4 MODEL

"type": "signalRTrigger",
"name": "invocation",
"hubName": "SignalRTest",
"category": "messages",
"event": "SendMessage",
"parameterNames": [
    "message"
],
"direction": "in"
 */

The new code:

import { app, HttpRequest, output, trigger, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function signalRTrigger(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {

    // **** - Add your signalR Azure Function code here

};

// This should provide the signalR upstream target to trigge
const signalTriggerConfig = trigger.generic({
    type: 'signalRTrigger',
    name: 'invocation',
    hubName: 'default',
    category: 'messages',
    event: 'SendMessage',
    parameterNames: [
       'message'
    ]
});


app.generic('signalr-trigger', {
    trigger: signalTriggerConfig,
    return: output.generic({
        type: 'http'
    }),
    handler: signalRTrigger
});

For the input and output binding make sure you have your local.settings.json and/or Azure Function configurations present or you'll get a 500 response error.

For the input binding:

/* 

V3 SYNTAX BEING CONVERTED TO V4 MODEL

{
  "type": "signalRConnectionInfo",
  "name": "connectionInfo",
  "hubName": "default",
  "connectionStringSetting": "AzureSignalRConnectionString",
  "direction": "in"
}
 */

I'm using the following code:

import { app, HttpRequest, input, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function negotiate(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {

    return {
        status: 200,
        body: JSON.stringify(context.options.extraInputs, null, 2) 
    };    

};

const signalRInput = input.generic({
    type: 'signalRConnectionInfo',
    name: 'connectionInfo',
    hubName: 'default',
})

app.http('negotiate', {
    methods: ['POST', 'GET'],
    authLevel: 'anonymous',
    handler: negotiate,
    extraInputs: [signalRInput]
});

For the output binding:

/* 

V3 SYNTAX BEING CONVERTED TO V4 MODEL

{
  "type": "signalR",
  "name": "signalRMessages",
  "hubName": "default",
  "connectionStringSetting": "AzureSignalRConnectionString",
  "direction": "out"
}
 */

I'm using the following code:

import { app, HttpRequest, output, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function signalRNotify(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {

    context.extraOutputs.get('signalRMessages') = [{
        'target': 'newMessage',
        'arguments': ['This is me calling.']
    }];

    return {
        status: 200,
        body: JSON.stringify('Message sent to SignalR', null, 2)
    };

};

// This should provide the signalR upstream target to trigge
const signalrOutput = output.generic({
    type: 'signalR',
    name: 'signalRMessages',
    hubName: 'default',
    connectionStringSetting: "AzureSignalRConnectionString"
});


app.http('signalr-notify', {
    methods: ['POST', 'GET'],
    authLevel: 'anonymous',
    handler: signalRNotify,
    extraOutputs: [signalrOutput]
});