Create a .NET client within minutes that connects to
the Diffusion™ server. This example creates a client that prints the value of a
topic to the console when the topic is updated.
To complete this example, you need a Diffusion server.
You also require either a named user that has a role with the select_topic and read_topic permissions or that anonymous client connections are assigned a role
with the select_topic and read_topic permissions. For example, the "CLIENT"
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 topic. The full
code example is provided after the steps.
-
Create a .NET project that
references the following DLL file located in the
clients/dotnet directory of your .NET installation:
- PushTechnology.ClientInterface.dll
- The assembly contains the interfaces classes and interfaces that you use when
creating a control client.
The .NET assembly is also available through NuGet.
Use the following command in the NuGet Package Manager Console:
PM> Install-Package PushTechnology.UnifiedClientInterface
-
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.Content;
using PushTechnology.ClientInterface.Client.Factories;
using PushTechnology.ClientInterface.Client.Features;
using PushTechnology.ClientInterface.Client.Features.Topics;
using PushTechnology.ClientInterface.Client.Topics.Details;
namespace PushTechnology.ClientInterface.GettingStarted {
public sealed class SubscribingClient {
}
}
-
Create a Main method.
public sealed class SubscribingClient
{
static void Main( string[] args ) {
}
}
}
-
In the Main method, connect to the Diffusion server.
static void Main( string[] args ) {
// Connect anonymously
// Replace 'host' with your hostname
var session = Diffusion.Sessions.Open("ws://host:port");
}
Or you can connect securely, using
Secure Sockets Layer (SSL):
Session session = Diffusion.sessions().Open("ws://host:port");
Or you can connect with a principal and credentials if that principal is assigned a
role with the
read_topic permission:
Session session = Diffusion.Sessions().Principal("principal")
.Password("password").Open("ws://host:port");
Replace the host, port, principal, and
password values with your own information.
-
Next, in the Main method, get the Topics feature.
// Get the Topics feature to subscribe to topics
var topics = session.GetTopicsFeature();
The Topics feature enables a client to
subscribe to a topic or fetch its state.
-
Within the subscribing client class, create an inner class that implements
IValueStream and overrides the OnTopicUpdate
method.
This inner class defines the behavior that occurs when a topic that the client
subscribes to is updated. In this example, the topic stream prints the topic name and the
content of the update to the console.
/**
* A topic stream that prints updates to the console.
*/
internal sealed class CounterTopicStream : IValueStream<IContent> {
/// <summary>
/// Notification of stream being closed normally.
/// </summary>
public void OnClose() {
Console.WriteLine( "The subscrption stream is now closed." );
}
/// <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"></param>
public void OnError( ErrorReason errorReason ) {
Console.WriteLine( "An error has occured : {0}", errorReason );
}
/// <summary>
/// Notification of a successful subscription.
/// </summary>
/// <param name="topicPath"></param>
/// <param name="specification"></param>
public void OnSubscription( string topicPath, ITopicSpecification specification ) {
Console.WriteLine( "Client subscribed to {0} ", topicPath );
}
/// <summary>
/// Notification of a successful unsubscription.
/// </summary>
/// <param name="topicPath">topic</param>
/// <param name="specification">the specification of the topic</param>
/// <param name="reason">error reason</param>
public void OnUnsubscription( string topicPath, ITopicSpecification specification, TopicUnsubscribeReason reason ) {
Console.WriteLine( "Client unsubscribed from {0} : {1}", topicPath, reason );
}
/// <summary>
/// Topic update received.
/// </summary>
/// <param name="topicPath">topic</param>
/// <param name="specification">the specification of the topic</param>
/// <param name="oldValue">value prior to update</param>
/// <param name="newValue">value after update</param>
public void OnValue( string topicPath, ITopicSpecification specification, IContent oldValue, IContent newValue ) {
Console.WriteLine( "New value of {0} is {1}", topicPath, newValue.AsString() );
}
}
-
Back in the Main method of the subscribing client class, use the
AddStream method to associate an instance of the topic stream
that you created with the topic you want to subscribe to.
// Add a topic stream for 'foo/counter' and request subscription
topics.AddStream(">foo/counter", new CounterTopicStream());
-
Next, use the Subscribe method to subscribe to the topic.
In this example, the topic subscribed to is foo/counter.
// Subscribe to the topic 'foo/counter'
topics.Subscribe("foo/counter", new TopicsCompletionCallbackDefault());
-
Use a Thread.sleep() to hold the client open for a minute while the
updates are received and output.
// Wait for a minute while the stream prints updates
Thread.Sleep( TimeSpan.FromMinutes( 1 ) );
session.Close();
-
Compile and run your client.
The client outputs the value to the console every time the value of the foo/counter topic is updated. You can update the value
of the foo/counter topic by creating a publishing client to update the topic. To create and publish
to the foo/counter topic, you require a user with
the modify_topic and update_topic permissions. For more information, see
Start publishing with .NET.
Full example
The completed subscribing client class contains
the following
code:
using System;
using System.Threading;
using PushTechnology.ClientInterface.Client.Callbacks;
using PushTechnology.ClientInterface.Client.Content;
using PushTechnology.ClientInterface.Client.Factories;
using PushTechnology.ClientInterface.Client.Features;
using PushTechnology.ClientInterface.Client.Features.Topics;
using PushTechnology.ClientInterface.Client.Topics.Details;
namespace PushTechnology.ClientInterface.GettingStarted {
/// <summary>
/// A client that subscribes to the topic 'foo/counter'.
/// </summary>
public sealed class SubscribingClient {
public static void Main( string[] args ) {
// Connect anonymously
var session = Diffusion.Sessions.Open( "url" );
// Get the Topics feature to subscribe to topics
var topics = session.GetTopicsFeature();
// Add a topic stream for 'foo/counter' and request subscription
topics.AddStream( ">foo/counter", new CounterTopicStream() );
topics.Subscribe( ">foo/counter", new TopicsCompletionCallbackDefault() );
//Stay connected for 1 minute
Thread.Sleep( TimeSpan.FromMinutes( 1 ) );
session.Close();
}
}
/// <summary>
/// A simple IValueStream implementation.
/// </summary>
internal sealed class CounterTopicStream : IValueStream<IContent> {
/// <summary>
/// Notification of stream being closed normally.
/// </summary>
public void OnClose() {
Console.WriteLine( "The subscrption stream is now closed." );
}
/// <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"></param>
public void OnError( ErrorReason errorReason ) {
Console.WriteLine( "An error has occured : {0}", errorReason );
}
/// <summary>
/// Notification of a succesfull subscription.
/// </summary>
/// <param name="topicPath"></param>
/// <param name="specification"></param>
public void OnSubscription( string topicPath, ITopicSpecification specification ) {
Console.WriteLine( "Client subscribed to {0} ", topicPath );
}
/// <summary>
/// Notification of a succesfull unsubscription.
/// </summary>
/// <param name="topicPath">topic</param>
/// <param name="specification">the specification of the topic</param>
/// <param name="reason">error reason</param>
public void OnUnsubscription( string topicPath, ITopicSpecification specification, TopicUnsubscribeReason reason ) {
Console.WriteLine( "Client unsubscribed from {0} : {1}", topicPath, reason );
}
/// <summary>
/// Topic update received.
/// </summary>
/// <param name="topicPath">topic</param>
/// <param name="specification">the specification of the topic</param>
/// <param name="oldValue">value prior to update</param>
/// <param name="newValue">value after update</param>
public void OnValue( string topicPath, ITopicSpecification specification, IContent oldValue, IContent newValue ) {
Console.WriteLine( "New value of {0} is {1}", topicPath, newValue.AsString() );
}
}
}