Receiving topic notifications
Receive topic notifications using topic selectors. This enables a client to receive updates when topics are added or removed, without the topic values.
Note: Topic notifications are supported by the Android™
API, Java™
API and JavaScript® API.
The client must register a listener object to receive notifications about selected topics. Use a topic selector to specify the topics.
For more details about topic notifications, see Topic notifications.
Required permissions:
and permissions for the specified topicsReceiving topic notifications
A client can register to receive notifications about a set of topics via a listener object.
JavaScript
var listener = { onDescendantNotification: function(topicPath, type) {}, onTopicNotification: function(topicPath, topicSpecification, type) {}, onClose: function() {}, onError: function(error) {} }; session.notifications.addListener(listener).then(function(reg) { reg.select("foo"); });
.NET
/** * Copyright © 2021 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 System.Threading.Tasks; using PushTechnology.ClientInterface.Client.Callbacks; using PushTechnology.ClientInterface.Client.Factories; using PushTechnology.ClientInterface.Client.Features; using PushTechnology.ClientInterface.Client.Features.Control.Topics; using PushTechnology.ClientInterface.Client.Session; using PushTechnology.ClientInterface.Client.Topics; using PushTechnology.ClientInterface.Client.Topics.Details; using static System.Console; namespace PushTechnology.ClientInterface.Example { /// <summary> /// Client implementation of a listener for topic notifications. /// </summary> public sealed class TopicNotificationListener { private const string TOPIC_PREFIX = "topic-notifications"; public TopicNotificationListener(string serverUrl) { var selector = $"?{TOPIC_PREFIX}//"; var session = Diffusion.Sessions.Principal( "control" ).Password( "password" ) .CertificateValidation((cert, chain, errors) => CertificateValidationResult.ACCEPT) .Open( serverUrl ); var notifications = session.TopicNotifications; INotificationRegistration registration = null; string path = string.Empty; // Register a listener to receive topic notifications. try { registration = await notifications.AddListenerAsync(new Listener()); } catch(Exception ex) { WriteLine($"Failed to add listener : {ex}."); session.Close(); return; } // Start receiving notifications. try { await registration.SelectAsync(selector); } catch (Exception ex) { WriteLine($"Selector '{selector}' registration failed : {ex}."); session.Close(); return; } // Add a topic. try { path = $"{TOPIC_PREFIX}/{DateTime.Now.ToFileTimeUtc()}"; var specification = session.TopicControl.NewSpecification(TopicType.STRING); await session.TopicControl.AddTopicAsync(path, specification); } catch (Exception ex) { WriteLine($"Failed to add topic '{path}' : {ex}."); session.Close(); return; } // Remove the topic. try { await session.TopicControl.RemoveTopicsAsync(path); } catch (Exception ex) { WriteLine($"Failed to remove topic '{path}' : {ex}."); session.Close(); return; } // Stop receiving notifications. try { await registration.DeselectAsync(selector); } catch (Exception ex) { WriteLine($"Deselection failed for selector '{selector}' : {ex}."); session.Close(); return; } // Unregister the listener. try { await registration.CloseAsync(); } catch (Exception ex) { WriteLine($"Failed to unregister the listener : {ex}."); } // Close the session session.Close(); } /// <summary> /// The listener for topic notifications. /// </summary> private class Listener : ITopicNotificationListener { /// <summary> /// Indicates that the stream was closed. /// </summary> public void OnClose() { WriteLine("The listener was closed."); } /// <summary> /// Notification for an immediate descendant of a selected topic path. /// </summary> public void OnDescendantNotification(string topicPath, NotificationType type) { WriteLine($"Descendant topic '{topicPath}' has been {type}."); } /// <summary> /// Indicates an error received by the callback. /// </summary> public void OnError(ErrorReason errorReason) { WriteLine($"The listener received the error: '{errorReason}'."); } /// <summary> /// Notification for a selected topic. /// </summary> public void OnTopicNotification(string topicPath, ITopicSpecification specification, NotificationType type) { WriteLine($"Topic '{topicPath}' has been {type}."); } } } }
Java and Android
final TopicNotifications notifications = session.feature(TopicNotifications.class); final TopicNotificationListener listener = new TopicNotificationListener() { @Override public void onTopicNotification(String topicPath, TopicSpecification specification, NotificationType type) { // Handle notifications for selected/deselected topics } @Override public void onDescendantNotification(String topicPath, NotificationType type) { // Handle notifications for immediate descendants } @Override public void onClose() { // The listener has been closed } @Override public void onError(ErrorReason error) { // The listener has encountered an error } }; final CompletableFuture<NotificationRegistration> future = notifications.addListener(listener); final NotificationRegistration registration = future.get(); registration.select("foo");