Tutorials
The below tutorials discuss how to use the various components of the Agora Edge Apps SDK. It provides a section on Getting Started and then tutorials on Logging, Configuration, Broker and BusClient.
Getting Started
Requirements
You can use the following methods to create an Agora Edge App. These are provided in separate documents. Make sure all the following tools installed on the developer machine.
- Using Visual Studio (Community/Professional/Enterprise)
- Using Visual Studio Code
- Using Command Line (Windows/Linux)
Logging Tutorial
By the end of the logging tutorial you should feel comfortable logging messages and understand logging level using the Agora Edge App SDK. There is nothing extremely special about the logging capability of the SDK compared to open source loggers, but it (like all others) has its own configuration settings which is integrally tied to the SDK's configuration capabilities.
Logging is required by the SDK to allow the SDK the ability to log information about itself.
Before you begin
You should have completed the Getting Started section to integrate the AgoraIoT.Edge.App.SDK into your project before starting and have a project ready to use with the tutorial.
Logging with String Extensions
In general, most logging can be accomplished just using String Extensions for Logging, which is what this tutorial focuses on.
From the IDE, open Program.cs
within the Console application created in the Getting Started tutorial and copy the code below into it:
public class Program
{
public static void Main(string[] args)
{
"Starting".LogHeading();
"Hello from Module!".LogWarn();
$"The current local time is {DateTime.Now}.".LogInfo();
"A debug message".LogDebug();
"A trace message".LogTrace();
"Stopping".LogHeading();
}
}
Run the application. You should see the output similar to what is below in the application's Console window.
-------------------------------------------------------------------------------
(33) Starting
-------------------------------------------------------------------------------
W(36) - Hello from Module!
I(36) - The current local time is 5/3/2022 5:17:13 PM.
-------------------------------------------------------------------------------
(37) Stopping
-------------------------------------------------------------------------------
Within the log, each message begins with the first letter of the LogLevel followed by the number of milliseconds since the application started in parentheses. If the LogLevel of the message being written is LogLevel.Info, the message will not contain the file, line number, and member name.
Notice that the Debug and Trace messages did not appear. This is because the Logging Level defaults to LogLevel.Info and above. To adjust the level of logging messages output by the Logger for troubleshooting and development use the AEA2:LogLevel
configuration setting. Assigning LogLevel sets the minimum level to be output, which corresponds to the LogLevel enumeration.
- Trace (0): Finest level of logging
- Debug (1): Used for debugging - specifically log values that should not go to Release
- Info (2): General logging information - filename, line number, and method are not included
- Warn (3): Used to indicate something is not happening as expected
- Error (4): Indicates an error occurred, but not fatally. Errors are used to indicate that the configuration error or unexpected software problem. It should not be used to log problems with the workflow or process that the application is performing.
- Fatal (5): Generally used just before the application is giving up, just before it stops.
- Off (6): Turns off all logging.
Additionally, the level of logging can be adjusted using configuration and by setting the level directly on the logger.
Configuration Settings affecting Logging using 'AEA.json' configuration file.
{
...
"AEA2": {
"LogLevel": "Debug"
}
...
}
Programmatically, the default logging level can be overridden calling the appropriate method on the logger.
Important
Setting LogLevel programmatically via the logger API can have unexpected results because Configuration changes will cause the LogLevel to be reset. To override any configuration setting, use configuration overrides.
Setting log level using the logger
Setting log level using configuration overrides
Configuration Tutorial
By the end of the configuration tutorial you should feel comfortable using the SDK Configuration capabilities and have an understanding of the dynamic nature of configuration which is an integral part for making your application configurable and modifiable - even while the application is running.
Before you begin
You should have completed the Getting Started tutorial to integrate the Agora.Edge SDK into your project before starting and have a project ready to use with the tutorial.
Adding 'AEA.json' and Naming your App
The default name for your application is the Entry Assembly Name. This Name can be overridden using Agora Edge App Configuration, which is very useful when configuring the application to interact with other applications.
Important
The Application Name (Config["Name"]
) is used as the MQTT Client identifier when routing messages.
To begin, copy the following code into the Program.cs
of your application.
using static Agora.SDK;
public class Program
{
public static void Main(string[] args)
{
"Starting".LogHeading();
$"Hello from {Config["Name"]}!".LogInfo();
"Stopping".LogHeading();
}
}
Running the application will produce an output similar to:
-------------------------------------------------------------------------------
(33) Starting
-------------------------------------------------------------------------------
I(36) - Hello from Module!
-------------------------------------------------------------------------------
(37) Stopping
-------------------------------------------------------------------------------
To override the name of the application:
- Add a json file to the project called
AEA.json
. - For .NET, in the Properties of the file, for 'Copy to Output Directory' select Copy if newer.
If using VSCode , add <None Update="AEA.json" CopyToOutputDirectory="PreserveNewest" />
in the csproj
file
<ItemGroup>
<PackageReference Include="AgoraIoT.Edge.App.SDK" Version="2.0.0" />
<None Update="AEA.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
To set the Name, open the AEA.json
file and add the following:
AEA.json
configuration file:
{
"Name": "MyApp"
}
Multiple Configuration Settings
Part I: Nested Settings
An AEA.json
file can contain nested settings.
Copy the contents below into your AEA.json
file of your application.
{
"Name": "MyApp",
"MyApp": {
"Setting1": "Value",
"Setting2": ["An", "Array", "of", "Values"]
}
}
The following codes shows how to access the settings.
Program.cs:
using System.Text;
using static Agora.SDK;
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine($"The name of my app is `{Config["Name"]}'");
Console.WriteLine($"Setting1 = `{Config["MyApp:Setting1"]}'");
/* Accessing a setting with an array */
var settings = Config.GetSection("MyApp:Setting2").GetChildren().AsEnumerable();
Console.Write("Setting2 contains `");
foreach (var s in settings)
Console.Write(s.Value + ' ');
Console.WriteLine("'.");
}
}
Output:
The name of my app is `MyApp'
Setting1 = `Value'
Setting2 contains `An Array of Values '.
Part II: Using Alternate, Key-Per-File, Environment Variable, and Command-Line Configuration
The purpose of the alternate and Key-Per-File configuration is to allow configuration of the application once it is deployed as a container. Typically, the container would be installed on a Gateway, and AgoraOps would configure the application as needed for the problem being addressed by the application.
The SDK looks for alternate configuration files in the config
folder, which AgoraOps configures to be a shared volume, for example, using the command:
docker run -v /var/app-configs/MyApp/config:/MyAppDir/config MyApp
For .NET applications, the config
folder is in the same folder as the starting application.
For Python, the 'config' folder is in the same folder where the python myapp.py
is executed.
The config
folder can contain the alternate configuration, config/AEA.json
and a folder with key-per-file settings config/keys/*
.
When running as a container, the SDK loads the configuration components in the following order:
- Default Settings: Set within the application.
- The Primary Config:
AEA.json
of the application - Environment Variables: 'AEA__*' variables.
- Command-line Arguments: ex. App -x=123 where -x is a switch map to settings within the application
- Alternate Config:
config/AEA.json
- Key-Per-File:
config/keys/*
- Override Settings: Set within the application.
To see how these work together, perform the following steps:
- Using the same
Program.cs
from the pervious tutorial go to the executing assembly folder. Generally this will be in thebin/Debug/net6.0
folder of the project. - Add a new directory called
config
. - Add a new alternate configuration file called
config/AEA.json
with the following contents and run the application.
{
"MyApp": {
"Setting1": "New Value for Setting 1"
}
}
File structure:
bin\
Debug\
net6.0\
config\AEA.json
Output:
The name of my app is `MyApp'
Setting1 = `New Value for Setting 1'
Setting2 contains `An Array of Values '.
You can also modify the configuration using environment variables, but since you cannot use ':' character in environment variable or in filenames, substitute '__' for the colons. Additionally, for environment variable to be recognized by the SDK, AEA__
must be prepended to the environment variables.
- Open a command window.
- Change directory / drive to the
bin/Debug/net6.0
of the project. - Run the command:
set AEA__MyApp__Setting1=Environment Variable Setting
- Run the application.
Output:
The name of my app is `MyApp'
Setting1 = `Environment Variable Setting'
Setting2 contains `An Array of Values '.
To modify the configuration using command line parameters execute one can use several methods. The following are equivalent methods that can be used as command-line arguments to modify MyApp:Setting1:
> <appName.exe> MyApp:Setting1=123
> <appName.exe> /MyApp:Setting1=123
> <appName.exe> --MyApp:Setting1=123
> <appName.exe> /MyApp:Setting1 123
> <appName.exe> --MyApp:Setting1 =123
> <appName.exe> --myapp:setting1 =123
Note
For .NET SDK, it is recommended by Microsoft not to mix multiple methods together.
Note
Settings (key names) are case insensitive.
Important
For Python SDK, the use of a switch map is required.
Executing any of the above will give:
The name of my app is `MyApp'
Setting1 = `123'
Setting2 contains `An Array of Values '.
Below shows how to modify or add an element to the array of MyApp:Setting2:
> set AEA__myapp__setting2__1=List
> <appName.exe>
The name of my app is `MyApp'
Setting1 = `Environment Variable Setting'
Setting2 contains `An List of Values '.
> <appName.exe> myapp:setting2:0=A
The name of my app is `MyApp'
Setting1 = `Environment Variable Setting'
Setting2 contains `A List of Values '.
Key-Per-File works very much like modifying environment variables.
Caution
Common Misunderstanding: When using Key-Per-File, the contents of the file is generally not JSON. The entire contents of the file is the value. I.e. The file name is the KEY and the file contents is the VALUE.
Create the file: config/keys/myapp__setting2__3
with the following contents:
Settings
Run the executable again and you should see:
> <appName.exe>
The name of my app is `MyApp'
Setting1 = `Environment Variable Setting'
Setting2 contains `An List of Settings
'.
Note
Make a note of the addition of the EOL character, which appears to be a bug in the Microsoft.Configuration.Extensions.
Part III: Responding To Configuration Changes
While your application runs at the edge, it is likely that you will want to make it respond to configuration changes. There are two ways to do this:
- The first method is to monitor for all configuration changes using the Config Reload Token which is part of the
Microsoft.Configuration.Extensions
. - The second method is to use an
Agora.ObservableSetting
.
Both methods are illustrated as below:
AEA.json:
{
"Name": "ConfigurationTutorial",
"Author": "Original Author",
"Authors": [ "Author1", "Author2" ]
}
Program.cs:
using static Agora.SDK;
public class Program
{
static public void Main()
{
"Starting".LogHeading();
WriteAuthor();
// Method 1
//Config.GetReloadToken().RegisterChangeCallback(InvokeChange, null);
//"If you modify any setting you will get a ReloadTokenChange".Cout();
// Method 2
//ObservableSetting.Get("Author").PropertyChanged += AuthorObservableSettingChanged;
//$"If you modify the 'Author' setting, you will get an ObservableSetting notifications.".Cout();
Console.ReadLine();
"Stopping".LogHeading();
}
private static void WriteAuthor() => $"Author is set to `{Config["Author"]}`".Cout();
private static void AuthorObservableSettingChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
WriteAuthor();
}
private static void InvokeChange(object o)
{
"Configuration Reloaded:".Cout();
WriteAuthor();
// You must re-register the change callback as the Configuration.ReloadToken has changed
Config.GetReloadToken().RegisterChangeCallback(InvokeChange, null);
}
}
Tip
When you use the method 1, you will notice each time you make a configuration change, you will get two callbacks. This is a known issue in the Microsoft.Extensions.Configuration and has been attributed to the system having to handle multiple operating systems which may or may not have file change callbacks and need to use file polling instead.
Both methods of handling configuration change may be used, even at the same time. If you uncomment the lines after each // Method
you can see what happens when you modify settings using the config/AEA.json
file and the key-per-files such as config/keys/authors
or config/keys/authors__0
.
Printing the Full Configuration
Sometimes it is necessary to understand the full configuration to assist in troubleshooting issues. Below shows how to use the SDK to write the configuration to logger as Info.
Microsoft.Extensions.Configuration does not currently have the ability to serialize an IConfiguration
, but the Agora Edge Apps SDK provides an extension method to do this.
var json = Config.SerializeToJson();
if ( json != null )
json.ToJsonString(new JsonSerializerOptions() { WriteIndented = true }).LogInfo();
Broker Tutorial
Agora Edge App Message Broker Tutorial
The examples in the section are pending inclusion of container images in a public docker registry. You should be able to get the overview of how this should work by just reading the text below until the container images are made publically available.
The Agora Edge App Message Broker can be run as a container on the gateway or in a development environment capable of running Linux containers.
To learn how the broker works, you can pull the container using the following command:
Note
Below commands will be usefull once container images are made available on Public Docker Registry
. Internal/Private Container Images are available on Agora Private Container Registry
.
docker pull agoraiot/AEA2-Broker
To run the broker, execute the following command:
docker run -rm -it -p 707:707 -v <configurationDir>:/var agoraiot/AEA2-Broker
where:
-rm
: removes container after it exits-it
: run in interactive mode-p
: maps host port (707) to container port (707)-v
: maps<configurationDir>
to container's/var
folder, which is used for configuration
The configuration folder, <configurationDir>
, can be a folder on the gateway or your development machine. For Windows, include the drive letter as shown:
Shared Volume (Windows): N:\repos\test\var
docker run -rm -it -p 707:707 -v /n/repos/test/var:/var agoraiot/AEA2-Broker
If you install Mosquitto, you can use the mosquitto clients to work with the Agora Edge Apps Broker.
With the broker running in a container, start a command window, and change directory to the mosquitto folder.
Note
The location of the mosquitto_sub
and mosquitto_pub
varies by operating system. For Windows this is likely to be C:\Program Files\Mosquitto
for x64 install or C:\Program Files (x86)\Mosquitto
for x86 install.
Start the Mosquitto subscriber to listen for DataIn
messages:
mosquitto_sub -p 707 -i Module1 -t DataIn
where:
- '-p 707' - the port for the broker
- '-t DataIn' - the topic being subscribed to
- '-i Module1' - the name of the client
To publish using Mosquitto publish to DataOut
:
mosquitto_pub -p 707 -t DataOut -i Module2 -m Hello
where:
- '-p 707' - the port for the broker. The default port is 707.
- '-t DataOut' - the topic you are publishing to. Internally, the broker converts this to 'Module2\DataOut'
- '-i Module2' - the name of the client
- '-m Hello' - the message
When you run the mosquitto_pub
, you will notice that nothing happens, i.e. the subscriber did not receive the message.
Note
Typically on an MQTT broker if one publishes data on a particular topic, it is received by someone listening to that topic. For example, publish a message to the Data
topic then a subscriber of the topic, Data
, will receive the message. And if you run the subscriber and publisher this way, directly against mosquitto, you would get that result.
For Agora Edge Apps, we do not want all data to flow between all applications, nor do we want each application to be concerned about where its data is going, i.e. configuring each application individually to publish data to topics or applications it knows nothing about. What we do instead is route the messages.
For the above mosquitto pub/sub to work, we need to configure the route in the Agora Edge App Broker.
To add a route create the <configurationDir>/AEA2-Broker/config/routes.json
file with the following contents:
{
"Routes": [
"/Module2/DataOut TO /Module1/DataIn"
]
}
if you run again the mosquitto_pub
command above, you should see the message was received by the subscriber.
Hello
Note that a few things happened.
- The AEA2-Broker is running as a container and is using port 707.
- The AEA2-Broker configuration folder is mapped to the
<configurationDir>
which is actively monitored. - When you create the file
routes.json
, the broker will see the file and load it. - When messages the
DataOut
message is received by the broker it uses the route specified inroutes.json
to convert it. It does this by using the client name of the sender and constructing the topic/Module2/DataOut
which it then looks up in the routing table to convert to/Module1/DataIn
, which the broker publishes.
Sending Data using Messaging
This tutorial instructs on how to send data to a Message Broker, in this case Mosquitto. Architecturally, the system being constructed in this Tutorial is shown below:
Normally, you will run your applications using the Agora Message Broker, which supports routing, but this tutorial is illustrating that underneath only MQTT is being used to communicate between the Apps and the purpose of the Broker, which should be clear if you consider that many senders and receivers are likely to be present when running on the edge.
To send messages using the Agora.SDK BusClient the BusClient is used. Ex. Bus.SendData(...)
.
To get started, from the IDE, open Program.cs within the Console application created in the Getting Started tutorial and copy the code below into Program.cs.
using static Agora.SDK;
internal class Program
{
private static void Main(string[] args)
{
"Starting".LogHeading();
Bus.Connect(90000);
Agora.Edge.Messages.DataReport.IoDataReportMsg msg = new();
msg.Add("999", "HKLD", new()
{
value = 10,
timestamp = (long)AgoraTimeStamp
});
Bus.SendData(msg);
Console.ReadLine();
"Stopping".LogHeading();
}
}
Add an AEA.json
to your project to configure the application. In this configuration file, you will specify the default port for the Mosquitto broker, 1883. Copy the contents below into the configuration file:
AEA.json:
{
"Name": "Sender",
"AEA2": {
"BusClient": {
"Port": 1883
}
}
}
Make sure the AEA.json is set to Copy to Output Directory. For Visual Studio, you set this as shown below:
Launch Mosquitto from the command line if it is not already running:
C:\Program Files\mosquitto> mosquitto
In another command window, launch a Mosquitto subscriber for the topic 'DataOut', which the Sender will be sending messages to.
C:\Program Files\mosquitto> mosquitto_sub -t DataOut
Run the Sender application and you should see the following from your Mosquitto Subscriber:
C:\Program Files\mosquitto>mosquitto_sub -t DataOut
{
"header": {
"SrcModule": "Sender",
"MessageType": "IODataReport",
"GroupID": "",
"LandingPoint": "AGORA_CLOUD",
"ConfigVersion": 1,
"MessageID": 252711801,
"TimeStamp": 1666266380177,
"Compressed": false,
"Format": "json"
},
"device": [
{
"id": "999",
"tags": {
"HKLD": {
"value": 10,
"timestamp": 1666266380177
}
}
}
]
}
Receiving Data using Messaging
The Sender application in the last tutorial is sending data to the broker using the DataOut
topic. However, an Agora Edge App does not receive DataOut
messages, it receives DataIn
messages. One of the purposes of the Agora Broker which runs on the edge and in your development environment is to transfer DataOut
messages to DataIn
messages as defined in the AEABroker's routes.json
configuration file. This assures that applications don't have to know about one another prior to deployment and centralizes the "wiring" of data paths between one another to a single location, while keeping messaging as generic as possible from the client's point-of-view.
For the Receiving Data tutorial, we again are not going to use the AEABroker, but instead will use mosquitto.
To start, copy the following code into your Program.cs:
using static Agora.SDK;
internal class Program
{
private static void Main()
{
"Starting".LogHeading();
Bus.Connect(90000);
while(true)
{
if(Bus.Messages.HasDataInMessages)
{
var data = Bus.Messages.GetDataInMessages();
foreach(var message in data)
{
foreach(var device in message.device)
{
foreach(var tag in device.tags)
{
var dt = Agora.Utilities.Time.GetDateTimeFromAgoraTimeStamp((double)tag.Value.timestamp!);
$"{tag.Key} = {tag.Value.value} @ {dt}".LogInfo();
}
}
}
}
Thread.Sleep(100);
}
}
}
Add an AEA.json to your project to configure the Name of the application. Copy the contents below into the configuration file:
AEA.json for `Receiver':
{
"Name": "Receiver",
"AEA2": {
"BusClient": {
"Port": 1883,
"UseDataIn": true
}
}
}
You can see in the configuration we have set "UseDataIn": true
. This tells the SDK that it should listen for DataIn
messages.
As you did in the Sending Data tutorial, make sure the AEA.json file is set to Copy to Output folder.
Start Mosquitto:
C:\Program Files\mosquitto> mosquitto
Create a Data Message to send to the Receiver. To do this, copy the following into a file, ex. %TEMP%/message.dat
.
{
"header": {
"SrcModule": "Sender",
"MessageType": "IODataReport",
"GroupID": "",
"LandingPoint": "AGORA_CLOUD",
"ConfigVersion": 1,
"MessageID": 252711801,
"TimeStamp": 1666266380177,
"Compressed": false,
"Format": "json"
},
"device": [
{
"id": "999",
"tags": {
"HKLD": {
"value": 10,
"timestamp": 1666266380177
}
}
}
]
}
Start the Receiver application.
Publish the message.dat
to the Mosquitto Broker.
C:\Program Files\mosquitto> mosquitto_pub -t DataIn -f %temp%\message.json
Bus Client Tutorial
Namespace: Agora.Edge
The BusClient is an integral part of Edge SDK 2.0 and is implemented as a Singleton. The purpose of the BusClient is to send and receive messages with the edge message broker.
IMPORTANT: The routes.json
provides the routes (a.k.a. topic mapping) so that messages can be routed between applications instead of publishing to all applications simultaneously. There is no facility to publish/subscribe to a global topic.
Configuration Parameters:
Name (string)
- Used to set the MQTT Client Name that identifies the client to the Broker. This is used for Routing purposes. Default:Entry Assembly Name
. Although "optional", it is recommended to specify the "Name" setting in theAEA.json
configuration file.AEA2:BusClient:Server (string)
: Server name hosting the MQTT Broker. Default:localhost
. Commonly, this is set tomqtt-net-server
when deployed in a container.AEA2:BusClient:Port (uint)
: Server Port for MQTT broker hosting the MQTT Broker. Default:707
.AEA2:BusClient:DeviceId (int)
: Default device id used when sending data from the application.AEA2:BusClient:Subscriptions (string array)
: Array of string topics to subscribe. Routing is required to receive messages. Default:<empty>
. Commonly,'DataIn'
, and'RequestIn'
are frequently used.
Example of AEA.json
configuration file:
{
"Name": "MyApp",
"AEA2": {
"BusClient": {
"Server": "localhost",
"Port": 707,
"DeviceId": 321,
"Subscriptions": ["DataIn", "RequestIn", "CustomTopic"]
}
}
}
Properties:
Instance: BusClient
- Used to access the Singleton instance and is the same as using the Agora.SDK.BusClient.IsConnected: bool
-True
if connected.Messages: BusMessageQueues
- Provides access to the queues used to store incoming messages.
Methods:
void Connect(int timeout_msec)
- Connects to the Bus using configuration settings.bool IsConnected()
- Returnstrue
if BusClient is connected.void SendData(IoDataReportMsg data, string msgTopic = "DataOut")
- Sends an IoDataReportMsg to the Bus. Messages are sent to the topic,msgTopic
which defaults to'DataOut'
.void SendRequest(RequestMsg request, string msgTopic = "RequestOut")
- Sends a RequestMsg to the Bus. Messages are sent to the topic,msgTopic
which defaults to'RequestOut'
.void SendMessage(string topic, MessageHeader header, string jsonMessage)
- Sends a json message as json"payload"
element andheader
as json"header"
element using the specifiedtopic
.async Task<bool> SendRawMessage(string topic, string message)
- Sends a rawmessage
as a string to the specifiedtopic
.void SendEvent(EventMsg eventmsg, string msgTopic = "EventOut")
- Sends a EventMsg to the Bus. Messages are sent to the topic,msgTopic
which defaults to'EventOut'
.
Redis Client Tutorial
This tutorial provides information about key-value NoSQL type technology.
Redis is a NoSQL key-value cache that stores information in a hash table format. It provides the possibilities to store different type of structured data like strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs.
With Edge SK 2.0 RedisClient functionality, developers can easily use Redis Server deployed on the gateway as a part of the Hermes Core Release.
Namespace: Agora.Edge
The RedisClient is implemented as a singleton. This singleton exposes a full-fledged RedisClient to interact with the server to store, retrieve values from Radis Server etc.
RedisClient can be configured from within the AEA.json
as shown below.
Configuration Parameters:
Name (string)
- Used to set the RedisClient Name that identifies the client to the server. Default:Entry Assembly Name
. Although "optional", it is recommended to specify the "Name" setting in theAEA.json
configuration file.AEA2:RedisClient:Server (string)
: Server name hosting the Redis Server. Default:localhost
. Commonly, this is set to the name of the container running Redis Server when deployed in a container.AEA2:RedisClient:Port (uint)
: Server Port hosting the Redis Server. Default:6379
. Commonly, this is set as a container create option with the port exposing Redis Server when deployed as a container.
Example of AEA.json
configuration file:
{
"Name": "Sender",
"AEA2": {
"LogLevel": "Trace",
"RedisClient": {
"Server": "localhost",
"Port": 6379,
}
}
}
Properties:
Instance: Redis
- Used to access the singleton instance and is the same as using the Agora.SDK.RedisClient.Client
- Used to access the Redis Server.IsConnected: bool
-True
if connected to Redis Server.
Methods:
void Connect(int timeout_msec)
- Connects to the Redis Server using configuration settings. If the server is not available, it will wait for timeout_msec and then it will try to connect in background. This is possible due to underneath Nuget Package StackExchange.Redis.public void Dispose()
- Cleans up resources required to keep the connection live to the Redis Server. Dispose makes underneath connection closed.
For Local Development and Testing
To get started with Redis Stack using docker, first you need to select a docker image:
redis/redis-stack
- contains both Redis Stack server and RedisInsight. This container is best for local development because yu can use the embedded RedisInsight to visualize your data.
To start a Redis Stack container using the Redis Stack image, run the following command in your terminal:
docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
Add an AEA.json
file to project with below setting:
{
"Name": "Sender",
"AEA2": {
"LogLevel": "Trace",
"RedisClient": {
"Server": "localhost",
"Port": 6379,
}
}
}
Create a Simple Console .NET Application
Programe.cs
using System.Text.Json;
using static Agora.SDK;
internal class Program
{
private static void Main(string[] args)
{
"Starting".LogHeading();
Redis.Connect(2000);
if (Redis.IsConnected)
{
var redisValues = Redis.Client?.ListRange("Key");
}
}
}
On running the app locally, Application should connect and print the below output.
Getting Started with the Agora Edge App .NET SDK
The .NET SDK provides functionality for developing .NET edge applications using .NET6.0 and above.
The .NET SDK is distributed on Nuget as AgoraIoT.Edge.App.SDK.
Several methods for getting started are provided using several environments, including:
- Command Line
- Visual Studio (Community, Pro, etc.)
- Visual Studio Code
Create a Console App
Pick the method you would like to create a new Console App.
Creating an Agora Edge App using Visual Studio 2022 and .NET Core 6
Create Console App:
- Start Visual Studio.
- Create a new project targeting a Console App (File > New Project...).
- Enter a Project Name, Location, and Solution Name.
- For the framework select .NET Core 6 (Long-term support).
Add 'AgoraIoT.Edge.App.SDK' NuGet Package:
- On the Solution Explorer, right click on the solution and select Manage Nuget Packages for Solution to bring up the NuGet Package Manager.
- Click the check box Include prerelease and make sure the Package Source is set to Nuget.
- Search for AgoraIoT.
- Select AgoraIoT.Edge.App.SDK in the list of packages.
- Agree to the License Agreement.
Creating an Agora Edge App using Visual Studio Code and .NET Core 6
Create Console App:
Follow the Microsoft tutorial to create a Console app, EXCEPT in Step 6 run the following commands:
> dotnet new console -n ProjectName -f net6.0 --use-program-main
> cd ProjectName
> dotnet add ProjectName.csproj package AgoraIoT.Edge.App.SDK --version 1.0.11-beta
Creating an Agora Edge App using Command Line and .NET Core 6
Create Console App:
From folder where you want to create a project within, enter
> dotnet new console -n ProjectName -f net6.0 --use-program-main
> cd ProjectName
> dotnet add ProjectName.csproj package AgoraIoT.Edge.App.SDK --version 1.0.11-beta
"Hello World!"
Replace the code in Program.cs with the following code and run the application:
"Hello World!".LogInfo();
Creating an Edge Application Container Image
Using the Dockerfile.sample provided within the application, create a Dockerfile for your project.
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/runtime-deps:6.0-alpine AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY src/. /src
RUN dotnet restore "ConsoleApp/ConsoleApp.csproj" -r linux-musl-x64
RUN dotnet build "ConsoleApp/ConsoleApp.csproj" -c Release -o /app/build --no-restore -r linux-musl-x64
FROM build AS publish
RUN dotnet publish "ConsoleApp/ConsoleApp.csproj" -p:PublishSingleFile=true -r linux-musl-x64 --self-contained true -p:PublishTrimmed=False -p:TrimMode=Link -c Release -o /app/publish --no-restore
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["./ConsoleApp"]
Create your docker container by running the following command within the project folder with the Dockerfile:
> docker build .
Getting Started with the Agora Edge App Python SDK
The Python SDK provides modules for developing an Agora Edge App using Python 3.8 or higher. All examples assume this has been installed.
You should also update 'pip':
> pip install -U pip
Create an Edge App
The Agora Edge App Python SDK provides the following modules combined within one Python package called agoraiot:
- agora_logging
- agora_busclient
- agora_config
- agora_utils
To install the package use:
> pip install agoraiot
"Hello World!"
Create a helloWorld.py
file:
from agoraiot import logger
logger.info("Hello World!")
Execute using Python:
> python helloWorld.py
Creating an Edge Application Container Image
Create the following files:
helloworld.py [from above]
Dockerfile
Dockerfile:
FROM alpine:3.17
USER root
ENV PATH="${PATH}:/sbin"
RUN apk add bash gcompat libc6-compat icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib python3 py3-pip
RUN pip install agoraiot
ADD ./src src
CMD python3 src/helloWorld.py
Run the following command:
> docker build .