콘텐츠로 이동
무료 평가 시작

구독과 게시 주기

값이 바뀔 때마다 알고 싶다면 Read를 반복하는 대신 구독(subscription)을 씁니다. 서버가 값을 샘플링하고, 바뀐 값만 알림(notification)으로 모아 보냅니다. MonitoredItem 서비스 집합은 Part 4 5.12절, Subscription 서비스 집합은 5.13절에서 정의합니다.

Subscription은 세션에 속한 알림 전달 단위입니다. 주요 매개변수는 다음과 같습니다.

매개변수 의미
publishingInterval 서버가 알림을 모아 보내는 주기(ms)
maxKeepAliveCount 보낼 알림이 없을 때 이 횟수만큼 주기가 지나면 빈 keep-alive 메시지를 보냅니다.
lifetimeCount 클라이언트의 Publish 요청 없이 이 횟수만큼 주기가 지나면 구독을 삭제합니다. keep-alive 횟수의 3배 이상이어야 합니다.
maxNotificationsPerPublish 메시지 하나에 담을 알림의 최대 개수
publishingEnabled 알림 전송 여부

MonitoredItem은 구독 안에서 감시할 대상입니다. 노드와 속성의 쌍(값이면 Value 속성, 이벤트면 EventNotifier 속성)을 감시합니다.

매개변수 의미
samplingInterval 서버가 값을 확인하는 주기(ms)
queueSize 게시 전까지 보관할 알림 수
discardOldest 큐가 넘치면 가장 오래된 알림을 버릴지 여부
filter 데이터 변경 필터(DataChangeFilter), 이벤트 필터(EventFilter) 등
clientHandle 클라이언트가 정한 번호. 알림에 그대로 돌아와 항목을 구분합니다.
monitoringMode Disabled, Sampling, Reporting

서버는 요청한 주기와 크기를 조정할 수 있습니다. 응답의 revised 값이 실제로 적용된 값입니다.

알림은 클라이언트가 먼저 보낸 Publish 요청의 응답으로 옵니다. 서버는 Publish 요청을 받아 두었다가, 게시 주기가 되면 그 응답에 알림을 담아 보냅니다.

Client Server
| CreateSubscription (publishingInterval) --> |
| CreateMonitoredItems (node, sampling) ----> | samples at samplingInterval,
| Publish ----------------------------------> | queues changed values
| Publish ----------------------------------> |
| <---- PublishResponse: seq 1, DataChangeNotification
| Publish (acknowledge seq 1) --------------> |
| <---- PublishResponse: seq 2, notifications
| ... no changes for keepAlive x interval ...
| <---- PublishResponse: keep-alive (no notifications)
  • 알림 메시지(NotificationMessage)에는 시퀀스 번호(sequence number)가 붙습니다. keep-alive 메시지는 다음 시퀀스 번호를 알려 줄 뿐 번호를 쓰지 않습니다.
  • 클라이언트는 다음 Publish 요청에서 받은 시퀀스 번호를 확인(acknowledge)합니다. 확인하지 않은 메시지는 서버가 재전송 큐에 보관합니다.
  • 시퀀스 번호가 비면 Republish로 빠진 메시지를 다시 요청합니다.
  • 클라이언트가 Publish 요청을 보내지 않으면 lifetimeCount 주기 뒤 구독이 사라집니다.

알림 데이터는 세 종류입니다. DataChangeNotification은 값 변화, EventNotificationList는 이벤트, StatusChangeNotification은 구독 상태 변화를 담습니다.

SDK. 클라이언트는 CreateSubscription(i=787), CreateMonitoredItems(i=751), Publish(i=826) 요청을 UA Binary로 만들어 pdcomm_opcua_client_begin으로 보냅니다. 메모리 서버는 이 서비스를 처리합니다. 예제의 ua_binary.h는 이 요청을 인코딩하지 않으므로, 완전한 UA Binary 인코더를 함께 씁니다. Publish 응답은 게시 주기 또는 keep-alive 주기만큼 늦게 도착하므로, 연결 옵션의 제한 시간(timeout_ms)을 그보다 길게 잡습니다.

시뮬레이터. subscribe 동작이 세션마다 구독 하나를 만들고 노드마다 MonitoredItem을 추가합니다. 설정값은 다음과 같습니다.

항목 값
게시 주기 interval_ms(50~10000 ms, 기본 250 ms). 세 주기의 합이 클라이언트 제한 시간보다 짧아야 합니다.
keep-alive 횟수, 수명 횟수 3, 30
샘플링 주기 게시 주기와 같음
큐 크기 10, 오래된 알림부터 버림
알림 보관 최대 1000개(limits.notification_queue). 넘치면 오래된 알림을 버리고 dropped를 늘립니다.

publish 동작은 Publish 요청을 보내고 응답을 기다립니다. 응답은 늦어도 keep-alive 주기 안에 옵니다. 빠진 시퀀스 번호는 Republish로 복구하고, 복구하지 못한 번호는 "kind":"gap" 항목으로 보고합니다. 구독 튜토리얼에서 실행합니다.

이벤트, 알람과 조건에서 같은 구독으로 이벤트를 받는 방법을 살펴봅니다.