Tutorial: Create a custom Kanzi Connect service

Kanzi Connect uses services to pass information from a Kanzi Connect service to a Kanzi Connect client, and then to the UI of an application. Kanzi Connect comes with several already defined services. However, when you want to create a service that provides functionality that the existing services do not have, you must create a custom Kanzi Connect service.

In the first part of this tutorial you learn how to create a custom Kanzi Connect service. After you create a service you then in the second part of the tutorial set that service to run on the Kanzi Connect Server and to use the Persistence Service.

For the list of services that come with Kanzi Connect, see Kanzi Connect services.

Assets for the tutorial

The <KanziConnectInstallation>/SDK/tutorials/Custom_service/Completed directory contains the completed tutorial.

Declare the interface of a service

You declare the interface of your Kanzi Connect service in the Simulator. The service interface is used by the Kanzi Connect client applications to compose messages that are exchanged through the Kanzi Connect network.

To declare the interface of a service:

  1. In Kanzi Studio create a project with the Kanzi Connect Client Application template.

    ../../_images/create-studio-project.png
  2. In the Kanzi Studio main menu select Kanzi Connect > Open Kanzi Connect Simulator.

    Kanzi Studio opens the Simulator in your default browser. If you do not have Kanzi Connect Server already running on this computer, this command also starts the Kanzi Connect Server that is installed on your computer.

    ../../_images/open-kanzi-connect-simulator2.png

    Note

    The Kanzi Connect Simulator officially supports only the Google Chrome web browser.

    ../../_images/simulator-default-service-model4.png
  3. In the Services panel click button-create and in the New Service window set:

    • Name to the name that you want to use

      This name appears in Kanzi Studio when you import services.

      For example, name the service MyService.

    • Namespace to the namespace that this service uses for code generation

      For example, set the namespace to myservice.

    • Package to the name for this service that you want to use on Android

      Note

      The default Package name is com.mycompany.connect.<servicename> in lowercase.

    • Description to a brief description that you want to use for this service in Kanzi Studio

    • Version to the version number

    ../../_images/add-service.png ../../_images/new-service-window.png
  4. Create the elements that define the content of your service.

    For example, add to the service runtime data, a method, and an event.

    1. To add runtime data to the service:

      1. In the Data section click create-button, select Group, and name the group MyData.

        ../../_images/simulator-create-data-group.png ../../_images/simulator-create-data-group-mydata.png
      2. In the Data section click create-button, select Data and set:

        1. Name to MyInteger

        2. Group to MyData

        3. Data Type to Integer

        ../../_images/simulator-create-myinteger.png
      3. Repeat the previous step, but create a float data type.

        ../../_images/simulator-create-myfloat.png
      ../../_images/simulator-mydata-myfloat-myinteger.png
    2. To add a method to the service, in the Methods section click add-button and set:

      1. Name to myMethod

      2. Return to Boolean

      3. In the Parameters section click add-button and set:

        1. Name to myMethodArgument

        2. Data Type to Float

      ../../_images/simulator-create-mymethod.png
    3. To add an event to the service, in the Events section click add-button and set:

      1. Name to myEvent

      2. In the Parameters section click add-button and set:

        1. Name to myEventArgument

        2. Data Type to String

      ../../_images/simulator-create-myevent.png
    ../../_images/simulator-myservice-content.png
  5. In the Simulator click Export > Native.

    The Simulator exports the description of your service to the myservice_interface.xml interface file.

    ../../_images/simulator-export-service.png
    <service fullname="Connect.Service.MyService" name="MyService" description="My custom service" namespace="myservice" type="simulated" version="0.1">
        <routing/>
        <event name="myEvent">
            <argument name="myEventArgument" datatype="string"/>
        </event>
        <method name="myMethod" return="bool">
            <argument name="myMethodArgument" datatype="float"/>
        </method>
        <runtime-data>
            <MyData>
                <MyInteger datatype="int" default="0" persistent="0" max="100" controller="Input" step="1" min="1"/>
                <MyFloat datatype="float" default="0.000000" persistent="0" max="1.0" controller="Input" step="0.01" min="0.0"/>
            </MyData>
        </runtime-data>
    </service>
    

You can now use the service for simulation and in Kanzi Studio.

Turn the interface definition into C++

Kanzi Connect comes with scripts that you can use to generate C++ code from the interface definition that you created in the previous section. This allows you to generate server-side and client-side service classes, and the communication code between them.

To turn the interface definition into C++:

  1. In the Simulator at the top of the Simulator window click new-project and name the project.

    Use a Simulator project to group a set of Simulator services and scenarios into a project file that you can export and share with those who work on the same project.

    When you create a Simulator project, the Simulator deletes any existing services and scenarios from the currently open Simulator project.

    ../../_images/simulator-create-project.png
  2. In the Simulator click Import and import the myservice_interface.xml interface file that you created in the previous section.

    ../../_images/simulator-import-services.png
  3. In the Simulator click export-project.

    The Simulator exports the project as a zip file that you can store on your computer.

    ../../_images/simulator-export-mysimulatorproject.png
  4. In Windows Explorer extract the Simulator project that you exported in the previous step.

    For example, extract the project in the <KanziConnectInstallation>/SDK/tutorials/Custom_service/ directory.

    The Simulator project contains these directories:

    • <KanziConnectInstallation>/SDK/tutorials/Custom_service/MySimulatorProject/interfaces

    • <KanziConnectInstallation>/SDK/tutorials/Custom_service/MySimulatorProject/configs

    See Kanzi Connect service template.

  5. In Kanzi Studio select File > Open Kanzi Command Prompt.

    This way you launch a Windows command prompt with the Kanzi environment variables set for the version of Kanzi based on the version of Kanzi Studio from which you opened a Kanzi Command Prompt.

    Use the Kanzi Command Prompt to build Kanzi projects, and access build tools and Kanzi utilities without writing absolute paths.

    ../../_images/open-kanzi-command-prompt.png

    Tip

    You can find the Kanzi Command Prompt in the Windows Start Menu in the Rightware directory.

    When you have more than one version of Kanzi installed, make sure that you launch a Kanzi Command Prompt for the version of Kanzi with which you want to work in that command prompt.

  6. In the Kanzi Command Prompt, go to directory:

    <KanziConnectInstallation>/SDK/tutorials/Custom_service/MySimulatorProject/interfaces
    

    and run the script generate_interfaces.py.

    Kanzi Connect creates source directory for each service in directory:

    <KanziConnectInstallation>/SDK/tutorials/Custom_service/MySimulatorProject/interfaces/definitions
    

    In this case, it creates directory:

    <KanziConnectInstallation>/SDK/tutorials/Custom_service/MySimulatorProject/sources/services/myservice_service
    

Create a library service for Windows

In this section you create a library service for Windows in Visual Studio.

To create a library service for Windows:

  1. Open the command line in the <KanziConnectInstallation>/SDK/tutorials/Custom_service/MySimulatorProject directory and run

    cmake -S . -B build -G "Visual Studio 16 2019" -DCMAKE_GENERATOR_PLATFORM=x64 -Tv142
    

    This way you generate the Visual Studio 2019 for the application.

  2. In Visual Studio open the <KanziConnectInstallation>/SDK/tutorials/Custom_service/MySimulatorProject/build/reference-services.sln Visual Studio solution.

  3. Select the solution configuration that you want to use and select Build > Build Solution.

Now that you created a custom service, you can set your custom service to run on the Kanzi Connect Server and set it to use the Persistence Service.

Set your service to run on the Kanzi Connect Server

In this section you set your service to run on the Kanzi Connect Server.

To set your service to run on the Kanzi Connect Server:

  1. In Visual Studio in the Soluton Explorer select project service_myservice, in the main menu select Project > Properties and in the Property Pages > Debugging set:

    • Command to

      $(KANZI_CONNECT_SDK)\lib\win64\GL_vs2019_$(Configuration)_DLL\connect_server.exe
      

      This way when you debug the library you launch the default Kanzi Connect Server executable.

    • Working Directory to

      $(OutDir)
      

      For the default Kanzi Connect Server to load the service binary the execution directory must be the directory where the compiled service library is.

    ../../_images/propertypagesdebugging.png
  2. Repeat the previous step for each configuration.

  3. In Visual Studio in the Solution Explorer right-click service_myservice and select Set as StartUp Project.

  4. In Visual Studio run your service in the Kanzi Connect Server by pressing the F5 key.

Note

You can use this same approach to debug your service on Windows. Now when you add a breakpoint in the myservice_service.cpp file in the onStartServiceRequest method and run your service, when the Kanzi Connect Server initializes, the execution hits the breakpoint you set.

../../_images/debuggingserver.png

Set your service to use the Persistence Service

The Persistence Service enables you to store in key-value pairs the information in Kanzi Connect Client applications and local and remote Kanzi Connect services and preserve that information through restarts of a Kanzi Connect Client application.

In this section you modify your service so that it uses the Kanzi Connect Persistence Service to store a value that it receives from the user interface of your application. You create a simple user interface in the next section.

To set your service to use the Persistence Service:

  1. If you started your service in the Kanzi Connect Server at the end of the previous section, in Visual Studio press Shift F5 to stop debugging.

  2. In the myservice_service.hpp file add the headers required by the Persistence Service:

    #include <kanzi/core/cpp/memory.hpp>
    #include <persistence_service/setting.hpp>
    
  3. In the myservice_service.hpp file in the private section create the pointer to the setting that you want to use with the Persistence Service:

    private:
        // Define a member variable for a persisted key-value pair for an integer data type.
        kanzi::unique_ptr<kanzi::connect::persistence::Setting<int>> m_mySetting;
    
  4. In the myservice_service.cpp file instantiate the setting that you want to use with the Persistence Service:

    namespace myservice
    {
    MyServiceService::MyServiceService() :
        // The MyServiceService cannot yet instantiate the setting because there is no
        // guarantee that the :guilabel:`Persistence Service` is ready.
        m_mySetting()
    {
        // Add implementation
    }
    
    ...
    
    void MyServiceService::initialize(kanzi::connect::InterfaceDomainBase* domain, kanzi::connect::ContentClientSharedPtr contentClient, kanzi::connect::WorkQueueInterface *workQueue)
    {
        MyServiceServiceConcept<MyServiceService>::initialize(domain, contentClient, workQueue);
    
        // Create a callback function that the Kanzi Connect Server invokes every time when the value of the setting changes.
        // Kanzi Connect Server invokes this function even from a service or client that is running in a separate process.
        auto settingChangeHandler = [](const string& settingName, const int& newValue)
        {
            kcLogInfo(("Setting {} new value is: {}", settingName, newValue));
        };
    
        // Instantiate the settings for the Persistence Service in the initialize at the earliest.
        // To access the instance that abstracts the settings creation use AbstractService::getSettingFactory().
        // This enables you to run your service in the same process where the Kanzi Connect Server is running
        // or in a remote process without having to change the service implementation.
        // Setting is not a concrete class and it can be either local or remote.
        // Create a setting key mySettingKey with initial value of 20, and set it to use the settingChangeHandler.
        // If you do not set an initial value the Persistence Service uses 0.
        m_mySetting = getSettingFactory()->createSettingUnique("mySettingKey", 20, settingChangeHandler);
    }
    ...
    }
    
  5. In Visual Studio run your service in the Kanzi Connect Server by pressing the F5 key.

Store a value from your application

In this section you take a value from the user interface of your application and use the Persistence Service to store that value.

To store a value from your application:

  1. In the Kanzi Studio main menu select Kanzi Connect > Open Kanzi Connect Editor.

    Use the Kanzi Connect Editor to create and manage connections to Kanzi Connect servers and services.

    ../../_images/kanzi-connect-kanzi-connect-editor2.png ../../_images/kanzi-connect-editor1.png
  2. In the Kanzi Connect Editor click + Add Connection and in the Select Connect Server window click Connect.

    That way you create a connection to a Kanzi Connect Server. You can see the connection in the Kanzi Connect Editor.

    • The Server IPV4 Address property sets the IP address of the Kanzi Connect Server that the Kanzi Studio Preview uses to connect to the server and look for Kanzi Connect services available on that server.

      Here you use the default Kanzi Connect Server running on the local host at the IP address 127.0.0.1.

    • The Server IP Address property sets the address of the Kanzi Connect Server that the client application uses during runtime.

    ../../_images/add-connection1.png ../../_images/connect-to-kanzi-connect-server1.png ../../_images/kanzi-connect-editor-with-connection1.png
  3. In the Kanzi Connect Editor click + Import Service, in the Import Connect Services window select the Persistence Service, and click Import. This way you import from the selected Kanzi Connect Server the Persistence Service service and the data sources that this service provides. The Data Sources window shows the data that is available through the Persistence Service service data sources.

    To view the Data Sources window, in the Kanzi Studio main menu select Window > Data Sources.

    ../../_images/import-connect-service1.png ../../_images/import-persistence-service.png ../../_images/connect-editor-persistence-service.png ../../_images/data-sources-persistence-service.png
  4. From the Asset Packages drag the Slider item to the Preview.

    ../../_images/assets-slider.png
  5. In the Library > Property Types create a property type whose Data Type is Text and click Save.

    ../../_images/create-string-property.png
  6. In the Node Tree select the Slider node and in the Properties:

    1. Add the property type you created in the previous step.

    2. Click + Add Binding and in the Binding Editor set:

      • Property to the property type you created earlier in this procedure

      • Expression to

        STRING({@./RangeConcept.Value})
        

        That way you convert the value of the Value property to a string and bind the value of the Value property in the Slider to the property type you created.

    ../../_images/slider-properties.png
  7. In the Node Components right-click Triggers to create a trigger that you want to use to tell the Persistence Service service to store the value that you want to preserve. For example, create the On Property Change trigger.

    ../../_images/slider-on-property-change.png
  8. In the On Property Change trigger set:

    • Node to <Relative> and .

    • Property Type to RangeConcept.Value

    This way you set the On Property Change trigger to set off the Persistence: writeSettingValue action every time the value of the Slider 2D node changes.

    ../../_images/trigger-condition.png
  9. In the On Property Change right-click Actions to create Persistence: writeSettingValue action and in the action editor set:

    • Persistence.writeSettingValue.key to the key you defined in the C++ code of the service you created earlier in this tutorial.

      For example, set this property to mySettingKey.

    • Persistence.writeSettingValue.value to the value that you want the Persistence Service to store.

      For example, next to the property name click image0, select Property and set the value to the property that you created and bound to the value of the Slider node Value property.

    ../../_images/on-property-change-writesettingvalue.png

In the Preview when you move the slider to change its value, the Persistence Service stores the value you set in the slider. You can see the value you set with the slider:

  • In your browser at http://localhost:8080/persistence/settings/mySettingKey You can use this web interface for debugging and viewing the available settings and their values during application development.

  • In the Kanzi Connect Server log window. The callback which you created in the tutorial writes these messages.