open62541pp 0.17.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/ua/types.hpp" // IntegerId, 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.14
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.14.2
64 * @{
65 */
66
67/**
68 * Subscription deletion callback.
69 * @param subId Subscription identifier
70 */
71using DeleteSubscriptionCallback = std::function<void(IntegerId 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(IntegerId subId, StatusChangeNotification& notification)>;
80
81namespace detail {
82std::unique_ptr<SubscriptionContext> createSubscriptionContext(
83 Client& connection,
84 StatusChangeNotificationCallback&& statusChangeCallback,
85 DeleteSubscriptionCallback&& deleteCallback
86);
87
88void storeSubscriptionContext(
89 Client& connection, IntegerId 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) {
131 auto context = detail::createSubscriptionContext(
132 connection, std::move(statusChangeCallback), std::move(deleteCallback)
133 );
134 return detail::AsyncServiceAdapter<CreateSubscriptionResponse>::initiate(
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 },
148 detail::HookToken(
149 [&, context = std::move(context)](const CreateSubscriptionResponse& response) mutable {
150 if (detail::getServiceResult(response).isGood()) {
151 detail::storeSubscriptionContext(
152 connection, response.subscriptionId(), 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.14.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, IntegerId 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) {
217 return detail::AsyncServiceAdapter<ModifySubscriptionResponse>::initiate(
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 IntegerId 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.14.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, IntegerId 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&, IntegerId, bool)
295 * @param token @completiontoken{void(StatusCode)}
296 * @return @asyncresult{StatusCode}
297 */
298template <typename CompletionToken>
300 Client& connection, IntegerId subscriptionId, bool publishing, CompletionToken&& token
301) {
302 const auto request = detail::createSetPublishingModeRequest(publishing, {&subscriptionId, 1});
304 connection,
305 asWrapper<SetPublishingModeRequest>(request),
306 detail::TransformToken(
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.14.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) {
340 return detail::AsyncServiceAdapter<DeleteSubscriptionsResponse>::initiate(
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, IntegerId 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>
372 Client& connection, IntegerId subscriptionId, CompletionToken&& token
373) {
374 const auto request = detail::createDeleteSubscriptionsRequest(subscriptionId);
376 connection,
377 asWrapper<DeleteSubscriptionsRequest>(request),
378 detail::TransformToken{
379 detail::getSingleStatus<UA_DeleteSubscriptionsResponse>,
380 std::forward<CompletionToken>(token)
381 }
382 );
383}
384#endif
385
386/**
387 * @}
388 * @}
389 */
390
391} // namespace opcua::services
392
393#endif
High-level client class.
Definition client.hpp:122
UA_StatusCode wrapper class.
Definition types.hpp:46
UA_CreateSubscriptionRequest wrapper class.
Definition types.hpp:2316
UA_CreateSubscriptionResponse wrapper class.
Definition types.hpp:2352
UA_DeleteSubscriptionsRequest wrapper class.
Definition types.hpp:2471
UA_DeleteSubscriptionsResponse wrapper class.
Definition types.hpp:2490
UA_ModifySubscriptionRequest wrapper class.
Definition types.hpp:2368
UA_ModifySubscriptionResponse wrapper class.
Definition types.hpp:2404
UA_SetPublishingModeRequest wrapper class.
Definition types.hpp:2419
UA_SetPublishingModeResponse wrapper class.
Definition types.hpp:2442
UA_StatusChangeNotification wrapper class.
Definition types.hpp:2458
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)
std::function< void(IntegerId subId)> DeleteSubscriptionCallback
Subscription deletion callback.
auto createSubscriptionAsync(Client &connection, const CreateSubscriptionRequest &request, StatusChangeNotificationCallback statusChangeCallback, DeleteSubscriptionCallback deleteCallback, CompletionToken &&token)
Create a subscription.
std::function< void(IntegerId subId, StatusChangeNotification &notification)> StatusChangeNotificationCallback
Subscription status change notification callback.
CreateSubscriptionResponse createSubscription(Client &connection, const CreateSubscriptionRequest &request, StatusChangeNotificationCallback statusChangeCallback, DeleteSubscriptionCallback deleteCallback)
Create a subscription.
DeleteSubscriptionsResponse deleteSubscriptions(Client &connection, const DeleteSubscriptionsRequest &request) noexcept
Delete subscriptions.
StatusCode deleteSubscription(Client &connection, IntegerId subscriptionId) noexcept
Delete a single subscription.
auto deleteSubscriptionsAsync(Client &connection, const DeleteSubscriptionsRequest &request, CompletionToken &&token)
Delete subscriptions.
auto deleteSubscriptionAsync(Client &connection, IntegerId 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:223
OPC UA services as free functions.
Definition attribute.hpp:21
uint32_t IntegerId
IntegerId.
Definition types.hpp:123
constexpr void throwIfBad(UA_StatusCode code)
Check the status code and throw a BadStatus exception if the status code is bad.
Definition exception.hpp:85
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.