Data Sharing Between Apps

Channels

.NET

Adding Channels to Your Application

Adding the Channel Selector

For .NET applications, you can add the channel selector at runtime:

IGlueWindows glueWindows = Glue.GlueWindows;
var glueWindowOptions = glueWindows?.GetStartupOptions() ?? new GlueWindowOptions();

// request channel support, so the window will show the Channel Selector.
glueWindowOptions.WithChannelSupport(true);

// any WPF window
System.Windows.Window window = this;

// see also Window Management for more details on registering windows as Glue42 windows
Glue.GlueWindows.RegisterWindow(window, glueWindowOptions)
    .ContinueWith(r =>
    {
        IGlueWindow glueWindow = r.Result;

        // see channel subscriptions and handling data
        glueWindow.ChannelContext.Subscribe(new LambdaGlueChannelEventHandler<T42Contact>(
            (context, channel, updatedContact) =>
            {
                T42Contact contact = updatedContact;
                HandleContact(contact);
            }, (context, newChannel, prevChannel) => 
            {
                // handle channel changed for this window
                T42Contact contact = context.GetValue<T42Contact>("contact");
                HandleContact(contact);
            }), "contact");
    });

The callback is invoked when:

  • The data from the channel you are currently on is updated.

The second callback (channel change handle) is invoked when:

  • You switch the channel and the application (window) is assigned to a new channel.
  • Your app (window) is not joined to a channel anymore (e.g. you have deselected the current channel). In this case, it will be undefined/null.

Channel Discovery

Your app can discover channels in 3 ways:

  • As a snapshot of the currently known channels:
// this will return an array of all currently known channels
IGlueChannel[] channels = Glue.Channels.GetChannels();
  • Through a subscription:
// the subscription lambda will be invoked for all current channels 
// and for any newly created channel
Glue.Channels.Subscribe(channel => HandleChannel(channel));
  • Awaiting a channel by name as a task, or awaiting a specific channel with a lambda filter:
// by name
Glue.Channels.AwaitChannel("Green").ContinueWith(...);

// with a lambda filter - allows finer filtering
Glue.Channels.AwaitChannel(channel => IsChannelInteresting(channel)).ContinueWith(...);

Joining a Channel

Once it finds a channel, your app can join it:

IGlueChannelContext glueChannelContext = Glue.Channels.JoinChannel(channel);

The glueChannelContext can then be used for reading, writing and subscribing to channel data.

Defining Channels

You can define any number of channels in Glue42 Enterprise for your applications to use - all you need to do is to configure them in the channels.json file in the %LocalAppData%\Tick42\GlueDesktop\config folder. Here is an example of adding a custom purple channel to an already existing list of channels in Glue42 Enterprise:

{
    "name": "Dark Purple",
    "meta": {
        "color": "#6400b0"
    }
}

Custom Channel

Subscribing for Data

To track the data in the current channel, use the subscribe() method:

Untyped Subscriptions

The event handler will be invoked on each channel update. The delta items contain the changed keys and values:

ChannelContext.Subscribe(new LambdaGlueChannelEventHandler(
    (context, channel, update) =>
    {
        DeltaItem[] added = update.Added;
        DeltaItem[] deltas = update.Deltas;
        DeltaItem[] removed = update.Removed;
    }, null), "contact");

Typed Subscriptions

An alternative to the untyped subscriptions are the typed subscriptions which ease the update handling:

ChannelContext.Subscribe(new LambdaGlueChannelEventHandler<string>(
    (context, channel, updatedValue) =>
    {
        // updated value is of the requested type: string
        string newFirstName = updatedValue;
        Console.WriteLine($"Name is {newFirstName}")
    }, null), "contact.name.firstName");

Or you can subscribe for the entire contact:

ChannelContext.Subscribe(new LambdaGlueChannelEventHandler<T42Contact>(
    (context, channel, updatedContact) =>
    {
        // updated value is of the requested type: T42Contact
        T42Contact contact = updatedContact;
        HandleContact(contact);
    }, null), "contact");

Reading Data from a Channel

  • Reading fields:

Let's read the contact's first and last name:

Console.WriteLine($"Contact is: {channelContext.GetValue<string>("contact.name.firstName")} {channelContext.GetValue("contact.name.lastName")}");

This demonstrates how to read string values from contact.name.firstName and contact.name.LastName.

  • Reading types:

As an alternative to reading value by value, you can define a type:

// excerpt from T42 Entities:
public class T42Contact
{
    public T42Id[] Ids { get; set; }

    public string DisplayName { get; set; }

    public T42Name Name { get; set; }
    ...
    // rest of the properties are removed for conciseness
}

public class T42Id
{
    public string SystemName { get; set; }
    public string NativeId { get; set; }
}

public class T42Name
{
    public string CompanyName { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string[] OtherNames { get; set; }
    public string Honorific { get; set; }
    public string[] PostNominalLetters { get; set; }
}

And read the T42Contact object directly from its location ("contact"):

if (channelContext.GetValue<T42Contact>("contact") is T42Contact contact)
{
    HandleContact(contact);
}

Publishing Data

You can use the SetValue() method to update the field of a context object:

glueChannelContext.SetValue("Jordan", "contact.name.firstName");

Or to update the entire object:

    T42Contact contact = ...;
    glueChannelContext.SetValue(contact, "contact");