Search code examples
pythonazuresignalrazure-signalr

Azure Signal R and Azure Function Python


I've been working on a project where we need to integrate Azure Signal R (or any backend/frontend notification system). I've been struggling to find documentation on how this works but found that the recommended integration for Python is to use an Azure function.

My workflow for usage would be the following :

  • Calling /negociate on my Azure function to get a new connectionId (or to set an userId):
    • This endpoint should call my backend to retrieve either an userId (I'm not using built in userId) or to send the connectionId so my backend can identify and make a link with the user.
    • If possible, I would like to pass a backend token along with the /negociate but I don't know if this is possible.
  • Connect to Signal R and receive notification.

Have you any example of code that achieved this ? Or specific documentation that explain the process. I find the Azure documentation to be very complex... I'm also not sure if this is the SignalR way of doing things...

Currently, all I have is :

import logging
import azure.functions as func

def main(req: func.HttpRequest, connectionInfo: str, context: func.Context) -> func.HttpResponse:
    logging.info(connectionInfo)
    return func.HttpResponse(
        connectionInfo,
        status_code=200,
        headers={
            'Content-type': 'application/json'
        }
    )

I want this /negociate endpoint to act so :

  • Only users connected to my backend can retrieve a connection to SignalR
  • My backend can map users to SignalR userId or connectionId But here connection info only have a token and an endpoint...

Thanks for your help !


Solution

  • Ok, Answering my own question here, what we ended up doing is something like that:

    • A GET method on the backend that will call the /negociate doing this:
    def main(req: func.HttpRequest, connectionInfo: str, context: func.Context) -> func.HttpResponse:
        return func.HttpResponse(
            connectionInfo,
            status_code=200,
            headers={
                'Content-type': 'application/json'
            }
        )
    

    Another entrypoint that will manage the others thing (send a message/etc.). So the Azure function is used with the admin key only by our backend. Here are the functions we use to:

    • Send a message to all users:
    def main(req: func.HttpRequest) -> str:
        message = req.get_json()
        return json.dumps({
            'target': 'newMessage',
            'arguments': [ message ]
        })
    
    • Send a message to a specific user
    def main(req: func.HttpRequest, context: func.Context) -> str:
        message = req.get_json()
        return json.dumps({
            'userId': message['userId'],
            'target': 'newMessage',
            'arguments': [ message ]
        })
    
    • Send a message to a group:
    def main(req: func.HttpRequest) -> str:
        message = req.get_json()
        return json.dumps({
            'groupName': message['groupName'],
            'target': 'newMessage',
            'arguments': [ message ]
        })
    
    • Add an user to a group
    def main(req: func.HttpRequest, action: func.Out[str]) -> func.HttpResponse:
        message = req.get_json()
        action.set(json.dumps({
            'userId': message['userId'],
            'groupName': message['groupName'],
            'action': 'add'
        }))
    

    The binding can change a little, but you can find the documentation here : https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-signalr-service