Create a .NET client that publishes data through
topics on
Diffusion™
Cloud
.
To complete this example, you need a
Diffusion
Cloud
service and a development system with the .NET
Framework installed on it. For more information about getting a
Diffusion
Cloud service, see Getting started with Diffusion Cloud.
You also require either a named user that has a role with the modify_topic and update_topic permissions. For example, the
"ADMINISTRATOR" role. For more information about roles and permissions, see
Role-based authorization.
This example steps through the lines of code required to subscribe to a JSON topic. The
full code example is provided after the steps.
-
Create a .NET
project that references the
DLL
file that
can be downloaded from the following location: Download the .NET
assembly
-
Diffusion.Client
- The assembly contains the interfaces classes and interfaces that you
use when creating a control client.
Use the following
.NET CLI command:
dotnet add package Diffusion.Client -v 6.11.6
-
In your project, create a C# file that uses the following packages:
using System;
using System.Threading;
using PushTechnology.ClientInterface.Client.Callbacks;
using PushTechnology.ClientInterface.Client.Factories;
using PushTechnology.ClientInterface.Client.Features.Control.Topics;
using PushTechnology.ClientInterface.Data.JSON;
namespace PushTechnology.ClientInterface.GettingStarted {
}
-
Create a Main method.
public sealed class PublishingClient
{
public static void Main( string[] args ) {
}
}
-
Inside the Main method, connect to
Diffusion
Cloud
.
public static void Main( string[] args ) {
// Connect using a principal with 'modify_topic' and 'update_topic'
// permissions
var session = Diffusion.Sessions.Principal("principal").Password("password").Open("ws://host:80");
}
Or you can connect securely to
Diffusion
Cloud
through port 443 using
Secure Sockets Layer (SSL):
.Open("wss://host:443");
Replace the host, principal, and
password values with your own information.
You can choose to connect anonymously if anonymous sessions are assigned the
modify_topic and update_topic permissions. However, we do
not recommend that anonymous sessions are given write access to data on
Diffusion
Cloud
.
-
Next, in the Main method, get the TopicControl and TopicUpdateControl features.
// Get the TopicControl and TopicUpdateControl features
var topicControl = session.TopicControl;
var updateControl = session.TopicUpdateControl;
The TopicControl feature enables a
client to create and delete topics. For more information, see .
The TopicUpdateControl feature
enables a client to publish updates to a topic. For more information, see .
-
Next, in the Main method, use the TopicControl feature to create the foo/counter JSON topic.
// Create a JSON topic 'foo/counter'
var topic = "foo/counter";
var addCallback = new AddCallback();
topicControl.AddTopicFromValue(
topic,
Diffusion.DataTypes.JSON.FromJSONString( "{\"date\":\"To be updated\",\"time\":\"To be updated\"}" ),
addCallback );
// Wait for the OnTopicAdded callback, or a failure
if ( !addCallback.Wait( TimeSpan.FromSeconds( 5 ) ) ) {
Console.WriteLine( "Callback not received within timeout." );
session.Close();
return;
} else if ( addCallback.Error != null ) {
Console.WriteLine( "Error : {0}", addCallback.Error.ToString() );
session.Close();
return;
}
The AddTopicFromValue() method requires a callback, which you must
create.
-
Implement an instance of ITopicControlAddCallback as an
internal sealed class.
internal sealed class AddCallback : ITopicControlAddCallback {
private readonly AutoResetEvent resetEvent = new AutoResetEvent( false );
/// <summary>
/// Any error from this AddCallback will be stored here.
/// </summary>
public Exception Error {
get;
private set;
}
/// <summary>
/// Constructor.
/// </summary>
public AddCallback() {
Error = null;
}
/// <summary>
/// This is called to notify that a call context was closed prematurely, typically due to a timeout or the
/// session being closed.
/// </summary>
/// <remarks>
/// No further calls will be made for the context.
/// </remarks>
public void OnDiscard() {
Error = new Exception( "This context was closed prematurely." );
resetEvent.Set();
}
/// <summary>
/// This is called to notify that the topic has been added.
/// </summary>
/// <param name="topicPath">The full path of the topic that was added.</param>
public void OnTopicAdded( string topicPath ) {
Console.WriteLine( "Topic {0} added.", topicPath );
resetEvent.Set();
}
/// <summary>
/// This is called to notify that an attempt to add a topic has failed.
/// </summary>
/// <param name="topicPath">The topic path as supplied to the add request.</param>
/// <param name="reason">The reason for failure.</param>
public void OnTopicAddFailed( string topicPath, TopicAddFailReason reason ) {
Error = new Exception( string.Format( "Failed to add topic {0} : {1}", topicPath, reason ) );
resetEvent.Set();
}
/// <summary>
/// Wait for one of the callbacks for a given time.
/// </summary>
/// <param name="timeout">Time to wait for the callback.</param>
/// <returns><c>true</c> if either of the callbacks has been triggered. Otherwise <c>false</c>.</returns>
public bool Wait( TimeSpan timeout ) {
return resetEvent.WaitOne( timeout );
}
}
-
Back in the Main method, loop once a second updating the
foo/counter topic with an
incrementing count.
Use the updateControl.Updater.Update() method to update a
topic without locking that topic.
var updateCallback = new UpdateCallback( topic );
for ( var i = 0; i < 1000; ++i ) {
updateControl.Updater.Update( topic, i.ToString(), updateCallback );
Thread.Sleep( 1000 );
}
The Update() method requires a callback, which you must
create.
-
Implement an instance of ITopicUpdaterUpdateCallback as an
internal sealed class.
internal sealed class UpdateCallback : ITopicUpdaterUpdateCallback {
private readonly string topicPath;
/// <summary>
/// Constructor.
/// </summary>
/// <param name="topicPath">The topic path.</param>
public UpdateCallback( string topicPath ) {
this.topicPath = topicPath;
}
/// <summary>
/// Notification of a contextual error related to this callback.
/// </summary>
/// <remarks>
/// Situations in which <code>OnError</code> is called include the session being closed, a communication
/// timeout, or a problem with the provided parameters. No further calls will be made to this callback.
/// </remarks>
/// <param name="errorReason">A value representing the error.</param>
public void OnError( ErrorReason errorReason ) {
Console.WriteLine( "Topic {0} could not be updated : {1}", topicPath, errorReason );
}
/// <summary>
/// Indicates a successful update.
/// </summary>
public void OnSuccess() {
Console.WriteLine( "Topic {0} updated successfully.", topicPath );
}
}
-
Finally, in the Main method, close the session between your
client and
Diffusion
Cloud
.
// Close session
session.Close();
-
Compile and run your client.
The client publishes a value to the foo/counter topic
every second. You can subscribe to the foo/counter topic by using the
Diffusion
Cloud Dashboard's test client or by creating
a client to subscribe to the topic. For more information, see Start subscribing with .NET.
Full example
The completed publishing client class
contains the following
code: