open62541pp 0.16.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
subscription.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <functional>
5#include <memory>
6#include <utility> // forward
7
9#include "open62541pp/config.hpp"
10#include "open62541pp/detail/client_utils.hpp" // getHandle
19#include "open62541pp/types_composed.hpp" // StatusChangeNotification
20
21#ifdef UA_ENABLE_SUBSCRIPTIONS
22
23namespace opcua {
24class Client;
25} // namespace opcua
26
27namespace opcua::services {
28
29/**
30 * @defgroup Subscription Subscription service set
31 * Report notifications to the client.
32 *
33 * Note the difference between Subscriptions and MonitoredItems. Subscriptions are used to report
34 * back notifications. MonitoredItems are used to generate notifications. Every MonitoredItem is
35 * attached to exactly one Subscription. And a Subscription can contain many MonitoredItems.
36 *
37 * @see MonitoredItem
38 * @see https://reference.opcfoundation.org/Core/Part4/v105/docs/5.13
39 * @ingroup Services
40 * @{
41 */
42
43/**
44 * Subscription parameters with default values from open62541.
45 */
47 /// Cyclic interval in milliseconds that the subscription is requested to return notifications.
48 double publishingInterval = 500.0;
49 /// Delete the subscription after defined publishing cycles without sending any notifications.
50 uint32_t lifetimeCount = 10000;
51 /// Send keep-alive message after defined publishing cycles without notifications.
52 uint32_t maxKeepAliveCount = 10;
53 /// The maximum number of notifications per publish (0 if unlimited).
55 /// Relative priority of the subscription. Notifications with higher priority are sent first.
56 uint8_t priority = 0;
57};
58
59/**
60 * @defgroup CreateSubscription CreateSubscription service
61 * Create subscriptions. Subscriptions monitor a set of monitored items for notifications and return
62 * them to the client.
63 * @see https://reference.opcfoundation.org/Core/Part4/v105/docs/5.13.2
64 * @{
65 */
66
67/**
68 * Subscription deletion callback.
69 * @param subId Subscription identifier
70 */
71using DeleteSubscriptionCallback = std::function<void(uint32_t subId)>;
72
73/**
74 * Subscription status change notification callback.
75 * @param subId Subscription identifier
76 * @param notification Status change notification
77 */
79 std::function<void(uint32_t subId, StatusChangeNotification& notification)>;
80
81namespace detail {
82std::unique_ptr<SubscriptionContext> createSubscriptionContext(
83 Client& connection,
84 StatusChangeNotificationCallback&& statusChangeCallback,
85 DeleteSubscriptionCallback&& deleteCallback
86);
87
89 Client& connection, uint32_t subscriptionId, std::unique_ptr<SubscriptionContext>&& context
90);
91} // namespace detail
92
93/**
94 * Create a subscription.
95 * @param connection Instance of type Client
96 * @param request Create subscription request
97 * @param statusChangeCallback Invoked when the status of a subscription is changed
98 * @param deleteCallback Invoked when the subscription is deleted
99 */
101 Client& connection,
102 const CreateSubscriptionRequest& request,
103 StatusChangeNotificationCallback statusChangeCallback,
104 DeleteSubscriptionCallback deleteCallback
105);
106
107/// @overload
109 Client& connection,
110 const SubscriptionParameters& parameters,
111 bool publishingEnabled,
112 StatusChangeNotificationCallback statusChangeCallback,
113 DeleteSubscriptionCallback deleteCallback
114) noexcept;
115
116#if UAPP_HAS_ASYNC_SUBSCRIPTIONS
117/**
118 * @copydoc createSubscription(Client&, const CreateSubscriptionRequest&,
119 * StatusChangeNotificationCallback, DeleteSubscriptionCallback)
120 * @param token @completiontoken{void(CreateSubscriptionResponse&)}
121 * @return @asyncresult{CreateSubscriptionResponse}
122 */
123template <typename CompletionToken>
125 Client& connection,
126 const CreateSubscriptionRequest& request,
127 StatusChangeNotificationCallback statusChangeCallback,
128 DeleteSubscriptionCallback deleteCallback,
129 CompletionToken&& token
130) {
132 connection, std::move(statusChangeCallback), std::move(deleteCallback)
133 );
135 connection,
136 [&, context = context.get()](UA_ClientAsyncServiceCallback callback, void* userdata) {
137 throwIfBad(UA_Client_Subscriptions_create_async(
138 opcua::detail::getHandle(connection),
139 asNative(request),
140 context,
141 detail::SubscriptionContext::statusChangeCallbackNative,
142 detail::SubscriptionContext::deleteCallbackNative,
143 callback,
144 userdata,
145 nullptr
146 ));
147 },
149 [&, context = std::move(context)](const CreateSubscriptionResponse& response) mutable {
150 if (detail::getServiceResult(response).isGood()) {
151 detail::storeSubscriptionContext(
152 connection, response.getSubscriptionId(), std::move(context)
153 );
154 }
155 },
156 std::forward<CompletionToken>(token)
157 )
158 );
159}
160
161/// @overload
162template <typename CompletionToken>
164 Client& connection,
165 const SubscriptionParameters& parameters,
166 bool publishingEnabled,
167 StatusChangeNotificationCallback statusChangeCallback,
168 DeleteSubscriptionCallback deleteCallback,
169 CompletionToken&& token
170) {
171 const auto request = detail::createCreateSubscriptionRequest(parameters, publishingEnabled);
173 connection,
174 asWrapper<CreateSubscriptionRequest>(request),
175 std::move(statusChangeCallback),
176 std::move(deleteCallback),
177 std::forward<CompletionToken>(token)
178 );
179}
180#endif
181
182/**
183 * @}
184 * @defgroup ModifySubscription ModifySubscription service
185 * Modify subscriptions.
186 * @see https://reference.opcfoundation.org/Core/Part4/v105/docs/5.13.3
187 * @{
188 */
189
190/**
191 * Modify a subscription.
192 * @param connection Instance of type Client
193 * @param request Modify subscription request
194 */
196 Client& connection, const ModifySubscriptionRequest& request
197) noexcept;
198
199/// @overload
201 Client& connection, uint32_t subscriptionId, const SubscriptionParameters& parameters
202) noexcept {
203 const auto request = detail::createModifySubscriptionRequest(subscriptionId, parameters);
204 return modifySubscription(connection, asWrapper<ModifySubscriptionRequest>(request));
205}
206
207#if UAPP_HAS_ASYNC_SUBSCRIPTIONS
208/**
209 * @copydoc modifySubscription(Client&, const ModifySubscriptionRequest&)
210 * @param token @completiontoken{void(ModifySubscriptionResponse&)}
211 * @return @asyncresult{ModifySubscriptionResponse}
212 */
213template <typename CompletionToken>
215 Client& connection, const ModifySubscriptionRequest& request, CompletionToken&& token
216) {
218 connection,
219 [&](UA_ClientAsyncServiceCallback callback, void* userdata) {
221 opcua::detail::getHandle(connection), asNative(request), callback, userdata, nullptr
222 ));
223 },
224 std::forward<CompletionToken>(token)
225 );
226}
227
228/// @overload
229template <typename CompletionToken>
231 Client& connection,
232 uint32_t subscriptionId,
233 const SubscriptionParameters& parameters,
234 CompletionToken&& token
235) {
236 const auto request = detail::createModifySubscriptionRequest(subscriptionId, parameters);
238 connection,
239 asWrapper<ModifySubscriptionRequest>(request),
240 std::forward<CompletionToken>(token)
241 );
242}
243#endif
244
245/**
246 * @}
247 * @defgroup SetPublishingMode SetPublishingMode service
248 * Enable/disable sending of notifications on subscriptions.
249 * Disable publishing of NotificationMessages of the subscription doesn't discontinue the sending
250 * of keep-alive messages, nor change the monitoring mode.
251 * @see https://reference.opcfoundation.org/Core/Part4/v105/docs/5.13.4
252 * @{
253 */
254
255/**
256 * Enable/disable publishing of notification messages of subscriptions.
257 * @param connection Instance of type Client
258 * @param request Set publishing mode request
259 */
261 Client& connection, const SetPublishingModeRequest& request
262) noexcept;
263
264/**
265 * @copydoc setPublishingMode(Client&, const SetPublishingModeRequest&)
266 * @param token @completiontoken{void(SetPublishingModeResponse&)}
267 * @return @asyncresult{SetPublishingModeResponse}
268 */
269template <typename CompletionToken>
271 Client& connection, const SetPublishingModeRequest& request, CompletionToken&& token
272) {
273 return detail::sendRequestAsync<SetPublishingModeRequest, SetPublishingModeResponse>(
274 connection, request, std::forward<CompletionToken>(token)
275 );
276}
277
278/**
279 * Enable/disable publishing of notification messages of a single subscription.
280 * @param connection Instance of type Client
281 * @param subscriptionId Identifier of the subscription returned by @ref createSubscription
282 * @param publishing Enable/disable publishing
283 */
285 Client& connection, uint32_t subscriptionId, bool publishing
286) noexcept {
287 const auto request = detail::createSetPublishingModeRequest(publishing, {&subscriptionId, 1});
288 return detail::getSingleStatus(
289 setPublishingMode(connection, asWrapper<SetPublishingModeRequest>(request))
290 );
291}
292
293/**
294 * @copydoc setPublishingMode(Client&, uint32_t, bool)
295 * @param token @completiontoken{void(StatusCode)}
296 * @return @asyncresult{StatusCode}
297 */
298template <typename CompletionToken>
300 Client& connection, uint32_t subscriptionId, bool publishing, CompletionToken&& token
301) {
302 const auto request = detail::createSetPublishingModeRequest(publishing, {&subscriptionId, 1});
304 connection,
305 asWrapper<SetPublishingModeRequest>(request),
307 detail::getSingleStatus<UA_SetPublishingModeResponse>,
308 std::forward<CompletionToken>(token)
309 )
310 );
311}
312
313/**
314 * @}
315 * @defgroup DeleteSubscriptions DeleteSubscriptions service
316 * Delete subscriptions.
317 * @see https://reference.opcfoundation.org/Core/Part4/v105/docs/5.13.8
318 * @{
319 */
320
321/**
322 * Delete subscriptions.
323 * @param connection Instance of type Client
324 * @param request Delete subscriptions request
325 */
327 Client& connection, const DeleteSubscriptionsRequest& request
328) noexcept;
329
330#if UAPP_HAS_ASYNC_SUBSCRIPTIONS
331/**
332 * @copydoc deleteSubscriptions
333 * @param token @completiontoken{void(DeleteSubscriptionsResponse&)}
334 * @return @asyncresult{DeleteSubscriptionsResponse}
335 */
336template <typename CompletionToken>
338 Client& connection, const DeleteSubscriptionsRequest& request, CompletionToken&& token
339) {
341 connection,
342 [&](UA_ClientAsyncServiceCallback callback, void* userdata) {
344 opcua::detail::getHandle(connection), asNative(request), callback, userdata, nullptr
345 ));
346 },
347 std::forward<CompletionToken>(token)
348 );
349}
350#endif
351
352/**
353 * Delete a single subscription.
354 * @param connection Instance of type Client
355 * @param subscriptionId Identifier of the subscription returned by @ref createSubscription
356 */
357inline StatusCode deleteSubscription(Client& connection, uint32_t subscriptionId) noexcept {
358 const auto request = detail::createDeleteSubscriptionsRequest(subscriptionId);
359 return detail::getSingleStatus(
360 deleteSubscriptions(connection, asWrapper<DeleteSubscriptionsRequest>(request))
361 );
362}
363
364#if UAPP_HAS_ASYNC_SUBSCRIPTIONS
365/**
366 * @copydoc deleteSubscription
367 * @param token @completiontoken{void(StatusCode)}
368 * @return @asyncresult{StatusCode}
369 */
370template <typename CompletionToken>
371auto deleteSubscriptionAsync(Client& connection, uint32_t subscriptionId, CompletionToken&& token) {
372 const auto request = detail::createDeleteSubscriptionsRequest(subscriptionId);
374 connection,
375 asWrapper<DeleteSubscriptionsRequest>(request),
377 detail::getSingleStatus<UA_DeleteSubscriptionsResponse>,
378 std::forward<CompletionToken>(token)
379 }
380 );
381}
382#endif
383
384/**
385 * @}
386 * @}
387 */
388
389} // namespace opcua::services
390
391#endif
High-level client class.
Definition client.hpp:121
UA_CreateSubscriptionRequest wrapper class.
UA_CreateSubscriptionResponse wrapper class.
UA_DeleteSubscriptionsRequest wrapper class.
UA_DeleteSubscriptionsResponse wrapper class.
UA_ModifySubscriptionRequest wrapper class.
UA_ModifySubscriptionResponse wrapper class.
UA_SetPublishingModeRequest wrapper class.
UA_SetPublishingModeResponse wrapper class.
UA_StatusChangeNotification wrapper class.
UA_StatusCode wrapper class.
Definition types.hpp:44
void(* UA_ClientAsyncServiceCallback)(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response)
UA_StatusCode UA_Client_Subscriptions_delete_async(UA_Client *client, const UA_DeleteSubscriptionsRequest request, UA_ClientAsyncServiceCallback callback, void *userdata, UA_UInt32 *requestId)
UA_StatusCode UA_Client_Subscriptions_modify_async(UA_Client *client, const UA_ModifySubscriptionRequest request, UA_ClientAsyncServiceCallback callback, void *userdata, UA_UInt32 *requestId)
auto createSubscriptionAsync(Client &connection, const CreateSubscriptionRequest &request, StatusChangeNotificationCallback statusChangeCallback, DeleteSubscriptionCallback deleteCallback, CompletionToken &&token)
Create a subscription.
std::function< void(uint32_t subId)> DeleteSubscriptionCallback
Subscription deletion callback.
CreateSubscriptionResponse createSubscription(Client &connection, const CreateSubscriptionRequest &request, StatusChangeNotificationCallback statusChangeCallback, DeleteSubscriptionCallback deleteCallback)
Create a subscription.
std::function< void(uint32_t subId, StatusChangeNotification &notification)> StatusChangeNotificationCallback
Subscription status change notification callback.
StatusCode deleteSubscription(Client &connection, uint32_t subscriptionId) noexcept
Delete a single subscription.
DeleteSubscriptionsResponse deleteSubscriptions(Client &connection, const DeleteSubscriptionsRequest &request) noexcept
Delete subscriptions.
auto deleteSubscriptionsAsync(Client &connection, const DeleteSubscriptionsRequest &request, CompletionToken &&token)
Delete subscriptions.
auto deleteSubscriptionAsync(Client &connection, uint32_t subscriptionId, CompletionToken &&token)
Delete a single subscription.
ModifySubscriptionResponse modifySubscription(Client &connection, const ModifySubscriptionRequest &request) noexcept
Modify a subscription.
auto modifySubscriptionAsync(Client &connection, const ModifySubscriptionRequest &request, CompletionToken &&token)
Modify a subscription.
SetPublishingModeResponse setPublishingMode(Client &connection, const SetPublishingModeRequest &request) noexcept
Enable/disable publishing of notification messages of subscriptions.
auto setPublishingModeAsync(Client &connection, const SetPublishingModeRequest &request, CompletionToken &&token)
Enable/disable publishing of notification messages of subscriptions.
constexpr NativeType * asNative(WrapperType *wrapper) noexcept
Cast Wrapper object pointers to native object pointers.
Definition wrapper.hpp:191
UA_Client * getHandle(Client &client) noexcept
void storeSubscriptionContext(Client &connection, uint32_t subscriptionId, std::unique_ptr< SubscriptionContext > &&context)
std::unique_ptr< SubscriptionContext > createSubscriptionContext(Client &connection, StatusChangeNotificationCallback &&statusChangeCallback, DeleteSubscriptionCallback &&deleteCallback)
OPC UA services as free functions.
Definition attribute.hpp:22
constexpr void throwIfBad(UA_StatusCode code)
Check the status code and throw a BadStatus exception if the status code is bad.
Definition exception.hpp:87
Subscription parameters with default values from open62541.
uint8_t priority
Relative priority of the subscription. Notifications with higher priority are sent first.
uint32_t maxKeepAliveCount
Send keep-alive message after defined publishing cycles without notifications.
uint32_t maxNotificationsPerPublish
The maximum number of notifications per publish (0 if unlimited).
uint32_t lifetimeCount
Delete the subscription after defined publishing cycles without sending any notifications.
double publishingInterval
Cyclic interval in milliseconds that the subscription is requested to return notifications.
Adapter to initiate open62541 async client operations with completion tokens.
static auto initiate(Client &client, Initiation &&initiation, CompletionToken &&token)
Initiate open62541 async client operation with user-defined completion token.
Special token to execute a hook function with the const result within the completion handler.
Special token to transform async results within the completion handler.