Subscribing to Data and Receiving Updates

Let’s take a look at some some simple examples of how client applications can use the StreamLink API. The examples contain some simple code fragments, illustrating how the API classes and methods are used. Since the StreamLink API is written in a number of different object oriented languages, the code fragments are in pseudo object oriented code – the actual implementation details will vary from one StreamLink SDK to another.

The StreamLink API operates asynchronously. This means that when the client code issues a subscription request or a command to StreamLink, the response is not returned immediately through the method used to issue the request or command. Instead, you must set up a listener object containing one or more callback methods, and then supply this listener to StreamLink. StreamLink calls the appropriate callback method(s) on the listener object, to communicate data and command responses back to the client code. This method of operation is shown in the following examples.

Implement the Interfaces

Before using StreamLink you need to implement as concrete classes an appropriate set of listener and other interfaces defined in the API User Layer. These implementations integrate StreamLink with your client application.

As a minimum, you must implement a SubscriptionListener. StreamLink calls the SubscriptionListener to handle subscription events.

For example, to deal with events concerning subscriptions to record-structured data, you need to implement on the SubscriptionListener the methods relating to record data. Your class should contain implementations of the methods onRecordUpdate(), onRecordType2Update(), onRecordType3Update(), to handle updates to type1, type2, and type 3 records respectively in a manner suitable for the client application. You can also implement methods for receiving permissions, containers, and directories. At run time, StreamLink passes in to each method both the subscription to which the event relates, and an event containing the updated fields as name-value pairs.

The SubscriptionListener may also implement an onSubscriptionError() method to deal with errors in subscriptions, and an onSubscriptionStatus() method to handle changes to the status of the subscription. (A status message relates to the state of the Liberator data services that handle the subscription, such as "Stale", "Limited", "OK". For more information about data services see DataSource.)

Depending on how Liberator is configured, you may need to prove that you have the right to connect to it. The typical way of doing this is with a username and password, which you can provide to the StreamLinkFactory.create method. In a production implementation the credentials would normally be provided by an implementation of a CredentialsProvider which could be much more sophisticated. For example, it could obtain login credentials from a database, a web site, or a single sign-on system. The credentials could take the form of a digitally signed secure token.

The following simple example shows how to use the StreamLink API to subscribe to a simple record containing a share price. The subject is /MSFT. This pattern is used for subscribing to all types of data.

The application will issue a subscription request to StreamLink, so the first thing to do is implement a SubscriptionListener that receives the updates resulting from the subscription. In the pseudo code fragments below the record subscription listener implementation is called MySubscriptionListener.

So, let’s get an instance of the StreamLink class using:

StreamLink streamLink = StreamLinkFactory.create({
                           liberator_urls: "rttp://liberator1:8080",
                           username: "demouser",
                           password: "demopass"
                           });

In StreamLink, there are variants of the constructor that enable you to obtain configuration from a properties file. The create() method also lets you set less common configuration options by passing in an optional StreamLinkConfiguration object.

2. Set up the record subscription listener

Next, we set up the listener using:

// Create an instance of a class that implements SubscriptionListener.
mySubsListener = new MyRecordSubscriptionListener();

3. Create a subscription

Now, create a subscription to /MSFT via the streamLink that you acquired earlier, supplying the subscription listener that will receive updates, events, and errors relating to the subscribed data item:

recordSubscription = streamLink.subscribe("/MSFT", mySubsListener);

By the way, the StreamLink API supports subscriptions to multiple data items using a single connection to the server. So there is no need to create multiple instances of the StreamLink class in order to make multiple requests. For example, you can subscribe to multiple records and receive updates into a single instance of RecordSubscriptionListener. However, StreamLink also allows you to register a different listener for each subscribed item. Let’s see how this works. The following example shows how to subscribe to both /MSFT and /YHOO and receive updates for both of these subjects into the same RecordSubscriptionListener:

msftRecordSubscription = streamLink.subscribe("/MSFT", mySubsListener);
yhooRecordSubscription = streamLink.subscribe("/YHOO", mySubsListener);

Note that StreamLink automatically batches multiple subscription requests into a single request call to maximize efficiency "over the wire".

When a client no longer wishes to receive updates to a subscribed data item it can unsubscribe from the item. This effectively discards it as far as the client is concerned. However, the item is still present on the Liberator, so the client can subsequently subscribe to it again if required. A client can also permanently delete an item from Liberator by executing the StreamLink Delete command. For this to succeed the client must have write access permission to that item on the Liberator .

4. Connect to the Liberator

Now, use the following to instruct StreamLink to connect to the Liberator defined in its configuration, and log in to the Liberator using the details previously set up in credentialsProvider:

streamLink.connect();

Some time later Liberator returns an image of the /MSFT record through a call to the onRecordUpdate() method of mySubsListener (instantiation of MyRecordSubscriptionListener). Subsequently, each time StreamLink receives an update to /MSFT, it calls onRecordUpdate(), passing the updated fields and their new values. You only need to connect to the Liberator once; subsequent subscription requests are passed to the Liberator immediately. You can make subscription requests before connecting to the Liberator; StreamLink queues them until a connection is established.

Note that StreamLink clients can also request all the data for a subject as at a single moment; this is called a snapshot. Snapshots return only the data currently in the Liberator’s cache, so the subject needs to be subscribed to first (if it is from an active DataSource). The snapshot method, StreamLink.Snapshot, is similar to the subscription method, StreamLink.Subscribe, except that it does not return a Subscription object.

The following example shows you how to request a snapshot of the data for the subject /MSFT. This example assumes that, as described in Subscribing to data and receiving updates , you have connected to Liberator, set up the record subscription listener (mySubsListener), and created a subscription to /MSFT.

streamLink.snapshot("/MSFT/", mySubsListener);