구독과 게시 주기
값이 바뀔 때마다 알고 싶다면 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은 구독 상태 변화를 담습니다.
PDComm에서
섹션 제목: “PDComm에서”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" 항목으로 보고합니다. 구독 튜토리얼에서 실행합니다.
다음 단계
섹션 제목: “다음 단계”이벤트, 알람과 조건에서 같은 구독으로 이벤트를 받는 방법을 살펴봅니다.