Registering and Binding different Azure services with Azure Cosmos DB Change Feed can be a challenge. Especially, if the service you are trying to use does not have an input or output trigger template. Azure SignalR is one of these services. SignalR can do magical things for your solution, but it can be a challenge to register it and use it in your solution. In this post, I will guide you to add Azure SignalR Service to your Cosmos DB Change Feed feature.

     SignalR allows server code to send asynchronous notifications to client-side web applications. By using it, Azure Functions can send real-time messages to your web applications. Prices can get change whenever data changes in database. Notices can be sent if user needs to be notified. Numbers in dashboard can change dynamically when data changes in Cosmos DB. You can do all those with Azure Cosmos DB + Azure Functions and SignalR. This combination works like David Copperfield magic.

    Let's say we own a Home Security Company; we sell security units to our customers with bunch of security sensors. Sensors connect to the main unit at a home and whenever a sensor detects something, Main unit sends a message to Azure Cosmos DB. We have Change Feed configured for CosmosDB to detect and do something whenever we receive a signal from any customer. You can find how to do that in my earlier post.

     In this post, I want to add Azure SignalR Service to this solution. I want to monitor Azure Functions by using SignalR. Whenever there will be a new signal, I want to display it on a web application which is used by employees.

    First, we need to create a Azure SignalR Service. Search for SignalR Service in Azure Portal and click on Create New.  Select Free for Pricing tier and keep Service Mode in Default. That's it to create an Azure SignalR Service. Click on Review Create and wait until it starts.



     We have Azure SignalR Service running, we can add this service to Azure Function now. First, you need to add SignalR Nuget packages to your function so you can call SignalR functions. Follow my older post about how to register Nuget packages to Azure functions. You must complete this part first. Without registering required Nuget packages, you cannot call SignalR Services.

     SignalR will be an output binding, there is no template for SignalR Service as output binding yet. We need to setup manually. Click on Integrate button under your Azure Function then click on Advanced Editor.



     Now you should see the function.json file. This file has all the binding information. You should have all the CosmosDB connections when you open it first time. Don't touch any of them, we need to add Nuget settings here. We need to add the following information into this file.


 "type": "signalR", 
 "name": "signalRMessages", 
 "hubName": "messages", 
 "direction": "out" 
 }

     type : It tells to Azure Function that this is a SignalR Service.
     name: This will display in Outputs drop down.
     hubName: This is the channel Azure function will use to send messages. SignalR works like a radio station, clients (web applications) need to be in the right channel to listen stations. In this case we are specifying which frequency we are going to use to send messages. You can name hubName whatever you like. You want to be sure that, you use the same name to listen these messages from your web application.
    direction: This can be input or output. In our case, it is out

     After you add this information, function.json should look like the following. Your CosmosDB Trigger information should be different that mine.



     We are ready to write some code to send messages to Azure SignalR Service. First, you must have a function named negotiate in your Azure Function. This function is required by SignalR, and it used to handshake with Azure SignalR Service. Only thing, you need to change in the following function is the HubName. Type your hubName there and add it to your Azure Function which receives messages from Azure CosmosDB

[FunctionName("negotiate")] 
public static SignalRConnectionInfo GetSignalRInfo([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req, [SignalRConnectionInfo(HubName="messages")] SignalRConnectionInfo connectionInfo)

 return connectionInfo; 



    Next, we need to add code which will be responsible to send messages to Azure SignalR Service.I am going to call this function sensorfired. We need to add SignalR parameter to the main function too.

[FunctionName("sensorfired")]
public static async Task Run(IReadOnlyList<Document> input,[SignalR(HubName="messages")]IAsyncCollector<SignalRMessage> signalRMessages, ILogger log)
{
if (input != null && input.Count > 0)
{
foreach(Document document in input)
{
Signal item = (dynamic)document;
await signalRMessages.AddAsync(new SignalRMessage{
Target = "sensorfired",
Arguments = new[] {item.SensorCode}
});
}
}
}


     Don't forget to use your hubName in this code, await signalRMessages.AddAsync is the line that sends a signal to Azure SignalR Services. Target is the name of the function which will run in client side when it receives this message. Arguments can be anything, this is the message you are passing to client side. You can check Azure SignalR usage charts to see the trafic. You should be able to see incoming messages from Azure Function after you have some changes in your CosmosDB.


     I will show you how to use Azure SignalR Service in your web application in my next post. So far, we have a system that detects the changes in Azure CosmosDB. For each change, it sends a signal to Azure SignalR Service. Next will be creating a web application that uses Azure SignalR Service to display these messages.

2

View comments

  1. This comment has been removed by the author.

    ReplyDelete
  2. Hi Hasan,
    Thanks for deep dive into technical aspects on the SignalR binding to Azure Function. I feel its a best in class among all articles , blogs and Videos across internet.
    Your post helped me to understand SignalR and Azure Function.

    ReplyDelete

     


     An embedding is a new way to represent data for Vector databases, machine learning models, and algorithms. Its format is similar to spatial data; rather than latitude and longitude, we have a bunch of vectors representing data. Just like spatial data, it is not really readable by users. It contains a bunch of floating-point numbers. Here is an example of embedding. The following numbers represent the text "Hello World!"


     1536 Floating points represent "Hello World"; now you are wondering if the number of floating points increases with the size of the text. I wonder how many floating points I need for "This is not my first rodeo. I have season tickets."



    As you can see, the length of the text does not change the number of floating points. This is good news. Embedding represents given data with 1539 floating points. You need to tell Azure OpenAI which model to use to generate embedding. The model you select controls the limits of the given input text. For example, I used the recommended model named text-embedding-ada-002 (Version 2) model to generate this embedding. The current input text limit for this model is 8192 tokens. What is a token? A Token can be words or chunks of characters depending on the words you have in a text. Here are some helpful rules for tokens from OpenAI.

1 token ~= 4 chars in English 1-2 sentences ~= 30 tokens
1 token ~= 3/4 words 1 paragraph ~= 100 tokens
100 tokens ~= 75 words 1500 words ~= 2048 tokens
  
    If you want to make a vector search in a database like Azure Cosmos DB MongoDB vcore, you must first convert your search parameter into an embedding/vector. To generate embeddings, you need to have Azure OpenAI feature. Then, you need to deploy the text-embedding-ada-002 model. The following screenshot shows you my deployed models. You must wait 5 to 10 minutes after the deployment to use a new model. 


     Next, you need the Azure.AI.OpenAI (1.0.0-beta9) or later version. Check the Include prerelease checkbox to find it in Visual Studio.


   You will need the URL and the credentials from the Azure Portal or in the Sample Code link in Azure AI Studio.



  1. You will need to use the endpoint and the key when you declare the OpenAIClient. 
  2. DeploymentName is the name of the text-embedding-ada-002 model deployment.
  3. Input is the text you want to convert into embedding/vector.

var client = new OpenAIClient(new Uri("endpoint goes here"), 
                              new AzureKeyCredential("key goes here"));
var options = new EmbeddingsOptions()
{
    DeploymentName = "embedding",
    Input = { "Generate this text into embedding" }
};

var vector = await client.GetEmbeddingsAsync(options);
foreach (var item in vector.Value.Data[0].Embedding.ToArray())
{
    Console.WriteLine(item);
}

0

Add a comment

Subscribe
Subscribe
About Me
About Me
My Photo
Hasan Savran is Microsoft Data Platform MVP and Microsoft Certified Solutions Developer. He works at Progressive Insurance as a Business Intelligence Architect. He spends his days architecting cutting edge business solutions by using the latest Web and Database technologies. Hasan has spoken at many SQL Saturdays, Code Camps and User groups.
Blog Archive
Loading
Powered by Blogger.