node-opcua-server
Version:
pure nodejs OPCUA SDK - module server
437 lines (436 loc) • 15.8 kB
TypeScript
/**
* @module node-opcua-server
*/
import { EventEmitter } from "events";
import { Duration, ISessionContext, IAddressSpace, UAVariable, UAObject, UAMethod } from "node-opcua-address-space";
import { Byte, UInt32 } from "node-opcua-basic-types";
import { SubscriptionDiagnosticsDataType } from "node-opcua-common";
import { AttributeIds, QualifiedNameLike } from "node-opcua-data-model";
import { DataValue, TimestampsToReturn } from "node-opcua-data-value";
import { NodeId } from "node-opcua-nodeid";
import { NumericRange } from "node-opcua-numeric-range";
import { ObjectRegistry } from "node-opcua-object-registry";
import { DataChangeNotification, EventNotificationList, MonitoringMode, MonitoredItemCreateResult, NotificationMessage, StatusChangeNotification, MonitoredItemCreateRequest } from "node-opcua-service-subscription";
import { StatusCode } from "node-opcua-status-code";
import { MonitoringFilter } from "node-opcua-types";
import { Queue } from "./queue";
import { MonitoredItem, QueueItem } from "./monitored_item";
import { ServerSession } from "./server_session";
import { IServerSidePublishEngine } from "./i_server_side_publish_engine";
export interface SubscriptionDiagnosticsDataTypePriv extends SubscriptionDiagnosticsDataType {
$subscription: Subscription;
}
export declare enum SubscriptionState {
CLOSED = 1,// The Subscription has not yet been created or has terminated.
CREATING = 2,// The Subscription is being created
NORMAL = 3,// The Subscription is cyclically checking for Notifications from its MonitoredItems.
LATE = 4,// The publishing timer has expired and there are Notifications available or a keep-alive Message is
KEEPALIVE = 5,// The Subscription is cyclically checking for Notification
TERMINATED = 6
}
interface IGlobalMonitoredItemCounter {
totalMonitoredItemCount: number;
}
export interface SubscriptionOptions {
sessionId?: NodeId;
/**
* (default:1000) the publishing interval.
*/
publishingInterval?: number;
/**
* (default:10) the max Life Time Count
*/
maxKeepAliveCount?: number;
lifeTimeCount?: number;
/**
* (default:true)
*/
publishingEnabled?: boolean;
/**
* (default:0)
*/
maxNotificationsPerPublish?: number;
/**
* subscription priority Byte:(0-255)
*/
priority?: number;
publishEngine?: IServerSidePublishEngine;
/**
* a unique identifier
*/
id?: number;
serverCapabilities: ServerCapabilitiesPartial;
globalCounter: IGlobalMonitoredItemCounter;
}
export type Notification = DataChangeNotification | EventNotificationList | StatusChangeNotification;
export type Counter = number;
export interface ModifySubscriptionParameters {
/**
* requestedPublishingInterval =0 means fastest possible
*/
requestedPublishingInterval?: Duration;
requestedLifetimeCount?: Counter;
/**
* requestedMaxKeepAliveCount ===0 means no change
*/
requestedMaxKeepAliveCount?: Counter;
maxNotificationsPerPublish?: Counter;
priority?: Byte;
}
export interface GetMonitoredItemsResult {
/**
* array of serverHandles for all MonitoredItems of the subscription
* identified by subscriptionId.
*/
serverHandles: Uint32Array;
/**
* array of clientHandles for all MonitoredItems of the subscription
* identified by subscriptionId.
*/
clientHandles: Uint32Array;
statusCode: StatusCode;
}
export interface InternalNotification {
monitoredItemId?: number;
notification: QueueItem | StatusChangeNotification;
publishTime: Date;
start_tick: number;
}
export interface InternalCreateMonitoredItemResult {
monitoredItem?: MonitoredItem;
monitoredItemCreateRequest: MonitoredItemCreateRequest;
createResult: MonitoredItemCreateResult;
}
export interface MonitoredItemBase {
node: UAVariable | UAObject | UAMethod | null;
filter: MonitoringFilter | null;
monitoringMode: MonitoringMode;
timestampsToReturn: TimestampsToReturn;
discardOldest: boolean;
queueSize: number;
clientHandle: UInt32;
}
export type CreateMonitoredItemHook = (subscription: Subscription, monitoredItem: MonitoredItemBase) => Promise<StatusCode>;
export type DeleteMonitoredItemHook = (subscription: Subscription, monitoredItem: MonitoredItemBase) => Promise<StatusCode>;
export interface ServerCapabilitiesPartial {
maxMonitoredItems: UInt32;
maxMonitoredItemsPerSubscription: UInt32;
}
export interface IReadAttributeCapable {
readAttribute(context: ISessionContext | null, attributeId: AttributeIds, indexRange?: NumericRange, dataEncoding?: QualifiedNameLike | null): DataValue;
}
/**
* The Subscription class used in the OPCUA server side.
*/
export declare class Subscription extends EventEmitter {
static minimumPublishingInterval: number;
static defaultPublishingInterval: number;
static maximumPublishingInterval: number;
static maxNotificationPerPublishHighLimit: number;
static minimumLifetimeDuration: number;
static maximumLifetimeDuration: number;
/**
* maximum number of monitored item in a subscription to be used
* when serverCapacity.maxMonitoredItems and serverCapacity.maxMonitoredItemsPerSubscription are not set.
*/
static defaultMaxMonitoredItemCount: number;
/**
* @deprecated use serverCapacity.maxMonitoredItems and serverCapacity.maxMonitoredItemsPerSubscription instead
*/
protected static get maxMonitoredItemCount(): number;
static registry: ObjectRegistry;
publishEngine?: IServerSidePublishEngine;
id: number;
priority: number;
/**
* the Subscription publishing interval
* @default 1000
*/
publishingInterval: number;
/**
* The keep alive count defines how many times the publish interval need to
* expires without having notifications available before the server send an
* empty message.
* OPCUA Spec says: a value of 0 is invalid.
* @default 10
*
*/
maxKeepAliveCount: number;
/**
* The life time count defines how many times the publish interval expires without
* having a connection to the client to deliver data.
* If the life time count reaches maxKeepAliveCount, the subscription will
* automatically terminate.
* OPCUA Spec: The life-time count shall be a minimum of three times the keep keep-alive count.
*
* Note: this has to be interpreted as without having a PublishRequest available
* @default 1
*/
lifeTimeCount: number;
/**
* The maximum number of notifications that the Client wishes to receive in a
* single Publish response. A value of zero indicates that there is no limit.
* The number of notifications per Publish is the sum of monitoredItems in the
* DataChangeNotification and events in the EventNotificationList.
*
* @property maxNotificationsPerPublish
* @default 0
*/
maxNotificationsPerPublish: number;
publishingEnabled: boolean;
subscriptionDiagnostics: SubscriptionDiagnosticsDataTypePriv;
publishIntervalCount: number;
/**
* number of monitored Item
*/
monitoredItemIdCounter: number;
private _state;
set state(value: SubscriptionState);
get state(): SubscriptionState;
messageSent: boolean;
$session?: ServerSession;
get sessionId(): NodeId;
get currentLifetimeCount(): number;
get currentKeepAliveCount(): number;
private _life_time_counter;
protected _keep_alive_counter: number;
_pending_notifications: Queue<InternalNotification>;
private _sent_notification_messages;
private readonly _sequence_number_generator;
private readonly monitoredItems;
private timerId;
private _hasUncollectedMonitoredItemNotifications;
private globalCounter;
private serverCapabilities;
constructor(options: SubscriptionOptions);
getSessionId(): NodeId;
toString(): string;
/**
* modify subscription parameters
* @param param
*/
modify(param: ModifySubscriptionParameters): void;
/**
* set publishing mode
* @param publishingEnabled
*/
setPublishingMode(publishingEnabled: boolean): StatusCode;
/**
* @private
*/
get keepAliveCounterHasExpired(): boolean;
/**
* Reset the Lifetime Counter Variable to the value specified for the lifetime of a Subscription in
* the CreateSubscription Service( 5.13.2).
* @private
*/
resetLifeTimeCounter(): void;
/**
* @private
*/
increaseLifeTimeCounter(): void;
/**
* True if the subscription life time has expired.
*
*/
get lifeTimeHasExpired(): boolean;
/**
* number of milliseconds before this subscription times out (lifeTimeHasExpired === true);
*/
get timeToExpiration(): number;
get timeToKeepAlive(): number;
/**
* Terminates the subscription.
* Calling this method will also remove any monitored items.
*
*/
terminate(): void;
setTriggering(triggeringItemId: number, linksToAdd: number[] | null, linksToRemove: number[] | null): {
statusCode: StatusCode;
addResults: StatusCode[];
removeResults: StatusCode[];
};
dispose(): void;
get aborted(): boolean;
/**
* number of pending notifications
*/
get pendingNotificationsCount(): number;
/**
* is 'true' if there are pending notifications for this subscription. (i.e moreNotifications)
*/
get hasPendingNotifications(): boolean;
/**
* number of sent notifications
*/
get sentNotificationMessageCount(): number;
/**
* @internal
*/
_flushSentNotifications(): NotificationMessage[];
/**
* number of monitored items handled by this subscription
*/
get monitoredItemCount(): number;
/**
* number of disabled monitored items.
*/
get disabledMonitoredItemCount(): number;
/**
* The number of unacknowledged messages saved in the republish queue.
*/
get unacknowledgedMessageCount(): number;
/**
* adjust monitored item sampling interval
* - an samplingInterval ===0 means that we use a event-base model ( no sampling)
* - otherwise the sampling is adjusted
* @private
*/
adjustSamplingInterval(samplingInterval: number, node?: IReadAttributeCapable): number;
/**
* create a monitored item
* @param addressSpace - address space
* @param timestampsToReturn - the timestamp to return
* @param monitoredItemCreateRequest - the parameters describing the monitored Item to create
*/
preCreateMonitoredItem(addressSpace: IAddressSpace, timestampsToReturn: TimestampsToReturn, monitoredItemCreateRequest: MonitoredItemCreateRequest): InternalCreateMonitoredItemResult;
applyOnMonitoredItem(functor: (monitoredItem: MonitoredItem) => Promise<void>): Promise<void>;
postCreateMonitoredItem(monitoredItem: MonitoredItem, monitoredItemCreateRequest: MonitoredItemCreateRequest, createResult: MonitoredItemCreateResult): void;
createMonitoredItem(addressSpace: IAddressSpace, timestampsToReturn: TimestampsToReturn, monitoredItemCreateRequest: MonitoredItemCreateRequest): Promise<MonitoredItemCreateResult>;
/**
* get a monitoredItem by Id.
* @param monitoredItemId : the id of the monitored item to get.
* @return the monitored item matching monitoredItemId
*/
getMonitoredItem(monitoredItemId: number): MonitoredItem | null;
/**
* remove a monitored Item from the subscription.
* @param monitoredItemId : the id of the monitored item to get.
*/
removeMonitoredItem(monitoredItemId: number): StatusCode;
/**
* rue if monitored Item have uncollected Notifications
*/
get hasUncollectedMonitoredItemNotifications(): boolean;
get subscriptionId(): number;
getMessageForSequenceNumber(sequenceNumber: number): NotificationMessage | null;
/**
* returns true if the notification has expired
* @param notification
*/
notificationHasExpired(notification: {
start_tick: number;
}): boolean;
/**
* returns in an array the sequence numbers of the notifications that have been sent
* and that haven't been acknowledged yet.
*/
getAvailableSequenceNumbers(): number[];
/**
* acknowledges a notification identified by its sequence number
*/
acknowledgeNotification(sequenceNumber: number): StatusCode;
/**
* getMonitoredItems is used to get information about monitored items of a subscription.Its intended
* use is defined in Part 4. This method is the implementation of the Standard OPCUA GetMonitoredItems Method.
* from spec:
* This method can be used to get the list of monitored items in a subscription if CreateMonitoredItems
* failed due to a network interruption and the client does not know if the creation succeeded in the server.
*
*/
getMonitoredItems(): GetMonitoredItemsResult;
/**
* @private
*/
resendInitialValues(): Promise<void>;
/**
* @private
*/
notifyTransfer(): void;
/**
*
* the server invokes the resetLifeTimeAndKeepAliveCounters method of the subscription
* when the server has send a Publish Response, so that the subscription
* can reset its life time counter.
*
* @private
*/
resetLifeTimeAndKeepAliveCounters(): void;
private _updateCounters;
/**
* _publish_pending_notifications send a "notification" event:
*
* @private
*
* precondition
* - pendingPublishRequestCount > 0
*/
_publish_pending_notifications(): void;
process_subscription(): void;
private _process_keepAlive;
private _stop_timer;
private _start_timer;
private _get_future_sequence_number;
get futureSequenceNumber(): number;
private _get_next_sequence_number;
get nextSequenceNumber(): number;
/**
* @private
*/
private _tick;
/**
* @private
*/
private _sendKeepAliveResponse;
/**
* Reset the Lifetime Counter Variable to the value specified for the lifetime of a Subscription in
* the CreateSubscription Service( 5.13.2).
* @private
*/
private resetKeepAliveCounter;
/**
* @private
*/
private increaseKeepAliveCounter;
/**
* @private
*/
private _addNotificationMessage;
/**
* @internal
* @param monitoredItemId
*/
private _removePendingNotificationsFor;
/**
* Extract the next Notification that is ready to be sent to the client.
* @return the Notification to send._pending_notifications
*/
private _popNotificationToSend;
/**
* discardOldSentNotification find all sent notification message that have expired keep-alive
* and destroy them.
* @private
*
* Subscriptions maintain a retransmission queue of sent NotificationMessages.
* NotificationMessages are retained in this queue until they are acknowledged or until they have
* been in the queue for a minimum of one keep-alive interval.
*
*/
private discardOldSentNotifications;
/**
* @param timestampsToReturn
* @param monitoredItemCreateRequest
* @param node
* @private
*/
private _createMonitoredItemStep2;
/**
*
* @param monitoredItem
* @param monitoredItemCreateRequest
* @private
*/
_createMonitoredItemStep3(monitoredItem: MonitoredItem | null, monitoredItemCreateRequest: MonitoredItemCreateRequest): void;
_harvestMonitoredItems(): void;
}
export {};