Just a second...

Start subscribing with .NET

Create a .NET client within minutes that connects to the Diffusion™ server. This example creates a client that prints the value of a JSON 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.
  1. Create a .NET project that references the following DLL file located in the clients/dotnet directory of your .NET installation:
    Diffusion.Client
    The assembly contains the interface classes and interfaces that you use when creating a control client.
    The .NET assembly is also available through NuGet.
    Use the following .NET CLI command:
    dotnet add package Diffusion.Client -v 6.2.0
  2. In your project, create a C# file that uses the following packages:
    using System.Threading;
    using System.Threading.Tasks;
    using PushTechnology.ClientInterface.Client.Callbacks;
    using PushTechnology.ClientInterface.Client.Factories;
    using PushTechnology.ClientInterface.Client.Features;
    using PushTechnology.ClientInterface.Client.Features.Topics;
    using PushTechnology.ClientInterface.Client.Topics.Details;
    using PushTechnology.ClientInterface.Data.JSON;
    using static PushTechnology.ClientInterface.Examples.Runner.Program;
    using static System.Console;
    
    namespace PushTechnology.ClientInterface.Example.Consuming {
      public sealed class ConsumingJSONTopics : IExample {
        
        }
    }
  3. Create a Main method.
        public sealed class SubscribingClient
        {
            public static void Main( string[] args ) {
         
            }
        }
  4. In the Main method, connect to the Diffusion server.
            public 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):
                var session = Diffusion.sessions().Open("wss://host:port");
    Or you can connect with a principal and credentials if that principal is assigned a role with the read_topic permission:
                var session = Diffusion.Sessions().Principal("principal")
                .Password("password").Open("wss://host:port");
    Replace the host, port, principal, and password values with your own information.
  5. Next, in the Main method, get the Topics feature.
            // Get the Topics feature to subscribe to topics
              var topics = session.Topics;
    The Topics feature enables a client to subscribe to a topic or fetch its state.
  6. Within the subscribing client class, create an inner class that implements IValueStream for a JSON topic.
    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 path and the content of the update to the console.
        internal sealed class JSONStream : IValueStream<IJSON> {
    
            public void OnClose() {
                Console.WriteLine( "The subscription stream is now closed." );
            }
    
            public void OnError( ErrorReason errorReason ) {
                Console.WriteLine( "An error has occured : {0}", errorReason );
            }
    
            public void OnSubscription( string topicPath, ITopicSpecification specification ) {
                Console.WriteLine( "Client subscribed to {0} ", topicPath );
            }
    
            public void OnUnsubscription( string topicPath, ITopicSpecification specification, TopicUnsubscribeReason reason ) {
                Console.WriteLine( "Client unsubscribed from {0} : {1}", topicPath, reason );
            }
    
            public void OnValue( string topicPath, ITopicSpecification specification, IJSON oldValue, IJSON newValue ) {
                Console.WriteLine( "New value of {0} is {1}", topicPath, newValue.ToJSONString() );
            }
        }
  7. 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. In this example, the topic path is "foo/counter".
              var topic = ">foo/counter";
              // Add a topic stream for 'foo/counter' and request subscription
              var jsonStream = new JSONStream();
              topics.AddStream( topic, jsonStream );
              topics.Subscribe( topic, new TopicsCompletionCallbackDefault() );
  8. Use a Thread.sleep() to hold the client open for 10 minutes while the updates are received and output.
              //Stay connected for 10 minutes
              Thread.Sleep( TimeSpan.FromMinutes( 10 ) );
            
              session.Close();
  9. 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:
          /**
 * Copyright © 2016, 2017 Push Technology Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using System.Threading;
using PushTechnology.ClientInterface.Client.Callbacks;
using PushTechnology.ClientInterface.Client.Factories;
using PushTechnology.ClientInterface.Client.Features;
using PushTechnology.ClientInterface.Client.Features.Topics;
using PushTechnology.ClientInterface.Client.Topics.Details;
using PushTechnology.ClientInterface.Data.JSON;

namespace PushTechnology.ClientInterface.Example {
    class Program {
        static void Main( string[] args ) {
            // Connect anonymously
            var session = Diffusion.Sessions.Open( "ws://localhost:8080" );

            // Get the Topics feature to subscribe to topics
            var topics = session.Topics;
            var topic = ">foo/counter";

            // Add a topic stream for 'random/JSON' and request subscription
            var jsonStream = new JSONStream();
            topics.AddStream( topic, jsonStream );
            topics.SubscribeAsync( topic ).Wait();

            //Stay connected for 10 minutes
            Thread.Sleep( TimeSpan.FromMinutes( 10 ) );

            session.Close();
        }

        /// <summary>
        /// Basic implementation of the IValueStream<TValue> for JSON topics.
        /// </summary>
        internal sealed class JSONStream : IValueStream<IJSON> {
            /// <summary>
            /// Notification of stream being closed normally.
            /// </summary>
            public void OnClose() 
                => Console.WriteLine( "The subscription 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">Error reason.</param>
            public void OnError( ErrorReason errorReason ) 
                => Console.WriteLine( $"An error has occured : {errorReason}" );

            /// <summary>
            /// Notification of a successful subscription.
            /// </summary>
            /// <param name="topicPath">Topic path.</param>
            /// <param name="specification">Topic specification.</param>
            public void OnSubscription( string topicPath, ITopicSpecification specification ) 
                => Console.WriteLine( $"Client subscribed to {topicPath}" );

            /// <summary>
            /// Notification of a successful unsubscription.
            /// </summary>
            /// <param name="topicPath">Topic path.</param>
            /// <param name="specification">Topic specification.</param>
            /// <param name="reason">Error reason.</param>
            public void OnUnsubscription( string topicPath, ITopicSpecification specification, TopicUnsubscribeReason reason ) 
                => Console.WriteLine( $"Client unsubscribed from {topicPath} : {reason}" );

            /// <summary>
            /// Topic update received.
            /// </summary>
            /// <param name="topicPath">Topic path.</param>
            /// <param name="specification">Topic specification.</param>
            /// <param name="oldValue">Value prior to update.</param>
            /// <param name="newValue">Value after update.</param>
            public void OnValue( string topicPath, ITopicSpecification specification, IJSON oldValue, IJSON newValue ) 
                => Console.WriteLine( $"New value of {topicPath} is {newValue.ToJSONString()}" );
        }
    }
}