Search Results

TIBCO FTL® C# Quick Start

Quick Start Contents

Introduction

This quick start guide focuses on a pair of TIBCO FTL sample applications written specifically for TIBCO Cloud Messaging (TCM): one publisher and one subscriber. The two applications also work with the TCM Demo.

Getting Started

Follow the steps below to get started using the sample applications:

  • Download and install the TIBCO FTL Messaging SDK and C# TCM Samples. This guide will refer to your FTL installation location as <ftl> and the sample location as <ftl-sample-path>.
  • The sample download contains:
    • Two (2) .NET Core applications with C# source
    • Two (2) sample .NET project files.
    • The FTL .NET DLLs to make running and building the sample convenient.
  • Download and install .NET Core 2.1 to run the pre-built samples. The FTL messaging SDK supports .NET Core 2.1 or greater.
  • Download your tcm-config.yaml (look for this icon ). This guide will refer to the tcm-config.yaml download locations as <tcm-config>. The sample applications do not take any arguments, instead they require your tcm-config.yaml to be present in the current working directory.
  • On Linux and macOS, add the <ftl>/<version>/bin and <ftl>/<version>/lib directories to your path and library path respectively. On Windows you only need to add <ftl>\<version>\bin to your path.

Running samples

Below are the instructions for running the pre-built DLLs included in the samples download.

Linux and macOS

> cd <ftl-sample-path>/dotnet
> export LD_LIBRARY_PATH=<ftl>/<version>/lib
> cp <tcm-config> .
> dotnet tcmdemopub.dll

Windows

> cd <ftl-sample-path>\dotnet
> set PATH=<ftl>\<version>\bin;%PATH%
> copy <tcm-config> .
> dotnet tcmdemopub.dll

Building samples

Below are the instructions for building the samples from the source files included in the samples download.

Linux and macOS

> cd <ftl-sample-path>/dotnet
> dotnet build tcmdemopub.csproj -f netcoreapp2.1 -o tcmdemopub
> cd tcmdemopub
> export LD_LIBRARY_PATH=<ftl>/<version>/lib
> cp <tcm-config> .
> dotnet tcmdemopub.dll

Windows

> cd <ftl-sample-path>\dotnet
> dotnet build tcmdemopub.csproj -f netcoreapp2.1 -o tcmdemopub
> cd tcmdemopub
> set PATH=<ftl>\<version>\bin;%PATH%
> copy <tcm-config> .
> dotnet tcmdemopub.dll

Description of sample applications

Publisher

Basic publisher program that demonstrates the use of publishing FTL messages.

Subscriber

Basic subscriber program that demonstrates the use of subscribing to FTL messages.

Run the Subscriber and Publisher at the same time to demonstrate real-time messaging. Stop the Subscriber, run the Publisher, and restart the Subscriber to demonstrate persistence.

Using the FTL SDK

To use the FTL SDK include the library and any third-party dependencies in your source files:

using TIBCO.FTL;

Client Configuration

The data required to configure a connection to the TCM server is available for download from your account Authentication Keys page as a YAML configuration file tcm-config.yaml. A trivial tcm-config.yaml file parser is provided below for illustration purposes.

public Dictionary<string, string> parseAppConfig(string configFile)
{
    Dictionary<string, string> options = new Dictionary<string, string>();
    System.IO.StreamReader file;
    string line;
    try
    {
        file = new System.IO.StreamReader(configFile);
    }
    catch (Exception e)
    {
        string message = string.Format("Failed to load configuration file: {0}", e.Message);
        throw new System.Exception(message);
    }
    while ((line = file.ReadLine()) != null)
    {
        line = line.Trim();
        if (!line.StartsWith("#"))
        {
            String[] nameValue = line.Split(":", 2);
            if (nameValue.Length != 2)
            {
                throw new System.Exception("Failed to parse configuration file");
            }
            String name = nameValue[0].Trim();
            String value = nameValue[1].Trim();
            options.Add(name, value);
        }
    }
    // Every TIBCO Cloud Messaging subscription has a unique URL
    if (!options.ContainsKey("ftl_url"))
    {
        throw new System.Exception("Failed to load realm URL from configuration file.");
    }
    // All connections to your TIBCO Cloud Messaging subscriptions must be authenticated.
    if (!options.ContainsKey("tcm_authentication_key"))
    {
        throw new System.Exception("Failed to load authentication key from configuration file.");
    }
    if (!options.ContainsKey("tcm_authentication_id"))
    {
        throw new System.Exception("Failed to load authentication id from configuration file.");
    }
    // Load server certificate for server verification.
    if (!options.ContainsKey("ftl_certificate"))
    {
        throw new System.Exception("Failed to load server certificate from configuration file.");
    }
    return options;
}

Configuring FTL Realm Properties

A properties object allows the client application to set attributes (or properties) for an object when the object is created. Declare realm property variables:

ITibProperties realmProps = null;
realmProps = FTL.CreateProperties();

A unique client label for each application will make tracking and monitoring easier.

realmProps.Set(FTL.REALM_PROPERTY_STRING_CLIENT_LABEL, "tcmdemopub.cs");

Configuring TCM authentication and server verification

Authentication using TCM specific authentication keys is required. The authentication id and key are located in the tcm-config.yaml.

realmProps.Set(FTL.REALM_PROPERTY_STRING_USERNAME, options["tcm_authentication_id"]);
realmProps.Set(FTL.REALM_PROPERTY_STRING_USERPASSWORD, options["tcm_authentication_key"]);

Use the trust file PEM certificate included in the tcm-config.yaml to verify the server you are Connect too.

realmProps.Set(FTL.REALM_PROPERTY_LONG_TRUST_TYPE, FTL.REALM_PROPERTY_HTTPS_CONNECTION_USE_SPECIFIED_TRUST_STRING);
string ftlCert = options["ftl_certificate"];

The PEM string contained in the tcm-config.yaml is modified to fit on a single line. Replace the ‘\n’ substring with a newline character to obtain a legal PEM string.

ftlCert = ftlCert.Replace("\\n", "\n");
realmProps.Set(FTL.REALM_PROPERTY_STRING_TRUST_PEM_STRING, ftlCert);

Establishing a connection

Establish a connection to TCM. Specify a string containing the realm service URL, a string containing the application name, and the properties object created above. All values required for a FTL realm connection are contained in the tcm-config.yaml

realm = FTL.ConnectToRealmServer(options["ftl_url"], options["ftl_application"], realmProps);

Publishing a message

Before a message can be published, the publisher must be created on the previously-created realm. Specify the endpoint onto which the messages will be published. In this example we are using the “default” endpoint.

IPublisher pub = null;
pub = realm.CreatePublisher("default");

In order to send a message, the message object must first be created via a call to realm.CreateMessage. Specify the format name. Here the format demo_tcm is used. TCM only supports dynamic formats.

msg = realm.CreateMessage("demo_tcm");

A newly-created message is empty - it contains no fields. The next step is to add one or more fields to the message. msg.SetString adds a string field. In this example a string field named demo_tcm is added, with the value “message seq”.

String content = String.Format("message {0}", seq);
msg.SetString("demo_tcm", content);

Once the message is complete, it can be sent via pub.Send(). Specify the message to be sent.

pub.Send(msg);

Subscribing and receiving messages

Event Queue

For messages to be delivered to a client application, two things are required: 1) A subscriber object must be created on a particular endpoint 2) The created subscriber object must be added to an event queue to dispatch the received messages Before the subscriber object can be added to an event queue, the event queue must exist. So that is the first step. realm.CreateEventQueue creates an event queue. A properties object can optionally be specified.

queue = realm.CreateEventQueue();

Subscriber

Create the subscriber object by specifying the endpoint name, an optional content matcher, and an optional properties object:

sub = realm.CreateSubscriber("default", contentMatcher, subscriberProps);

The last step is to add the subscriber object to the event queue. This allows the event queue to dispatch messages sent to that subscriber. Specify the subscriber object, and an object which implements ISubscriberListener and provides a MessagesReceived method.

queue.AddSubscriber(sub, this);

Endpoints

TIBCO Cloud messaging only supports a fixed set of endpoints: default, shared, last-value and map. Each endpoint is associated with a durable type of the same name. If your application does not need persistence use the default endpoint.

Content Matcher

A content matcher is used to limit which messages are delivered to a client application based on the content of the message. The string passed to realm.CreateContentMatcher() contains JSON which specifies the field name in the message, and the required value of that field. In this case, {"demo_tcm":true} matches any message which contains the field demo_tcm.

contentMatcher = realm.CreateContentMatcher("{\"demo_tcm\":true}");

Subscriber Properties

A shared durable essentially acts like a queue. Messages are stored in the persistent server, and apportioned among active subscribers to the durable in a round-robin fashion. Each subscriber must specify the same durable name. The durable name is defined by properties specified when the subscriber is created. If your application does not need persistence do not supply a durable name.

subscriberProps = FTL.CreateProperties();
subscriberProps.Set(FTL.SUBSCRIBER_PROPERTY_STRING_DURABLE_NAME, "tcmdemosub.cs");

Dispatching

Begin dispatching messages

Console.WriteLine("Waiting for message(s)");
while (!finished)
{
    queue.Dispatch();
}

Message Callback

The method MessagesReceived is the message delivery callback method for this sample. Callbacks are associated with a subscriber via queue.AddSubscriber. The callback must be named MessagesReceived, be a member of a class which implements ISubscriberListener, return void, and take three arguments:

  • an array of messages (IMessage) being delivered to the callback in this invocation
  • an integer indicating the number of messages delivered to the callback in this invocation
  • an event queue (IEventQueue), the event queue which dispatched the messages More than one message may be delivered in a single invocation. The number of messages is contained in the count argument. Each message is an element in the messages argument. The callback must be able to handle the delivery of multiple messages.

Since more than one message may be delivered to this callback in a single invocation, loop through the messages and process them.

public void MessagesReceived(IMessage[] messages, ref int count, IEventQueue eventQueue)
{
    int i;
    for (i = 0; i < count; i++)
    {
        Console.WriteLine("Received " + (IMessage)messages[i]);
    }
}

Subscribing to Notifications

Register a notification handler which is invoked when an administrative action occurs which requires the client application to be notified. Specify an object which implements INotificationHandler, and provides an OnNotification() method.

realm.SetNotificationHandler(this);

OnNotification is the notification handler callback. In some situation, FTL must notify a client application of a condition which can’t be delivered through an event queue. Instead of sending an advisory (which would require an event queue), FTL uses an out-of-band mechanism to notify the client application. The notification callback must be named OnNotification, be a member of a class which implements INotificationHandler, return void, and take two arguments:

  • a RealmNotificationType which indicates the type of condition being notified
  • a string describing the reason for the notification
public void OnNotification(RealmNotificationType type, string reason)
{
    if (type == RealmNotificationType.CLIENT_DISABLED)
    {
        System.Console.WriteLine("Application administratively disabled: " + reason);
        finished = true;
    }
    else
    {
        System.Console.WriteLine("Notification type " + type + ": " + reason);
    }
}

Cleanup

Once objects are no longer needed, they should be disposed of - and generally in reverse order of creation.

Publisher

msg.Dispose();
pub.Dispose()
realm.Dispose();
realmProps.Dispose();

Subscriber

contentMatcher.Dispose();
queue.RemoveSubscriber(sub);
queue.Dispose();
sub.Dispose();
realm.Dispose();

To permanently destroy a durable subscription, including any messages stored by TIBCO Cloud Messaging for that durable, first close the subscription and then call unsubscribe using the realm object. Supply the unsubscribe call with the endpoint name and durable name used to create the durable subscription.

sub.Dispose();
realm.Unsubscribe("default", "tcmdemosub.cs");