UNPKG

node-opcua-client

Version:

pure nodejs OPCUA SDK - module client

383 lines (320 loc) 13.4 kB
/** * @module node-opcua-client */ // tslint:disable:no-unused-expression import { EventEmitter } from "events"; import { LocaleId } from "node-opcua-basic-types"; import { OPCUACertificateManager } from "node-opcua-certificate-manager"; import { OPCUASecureObject } from "node-opcua-common"; import { Certificate } from "node-opcua-crypto/web"; import { ObjectRegistry } from "node-opcua-object-registry"; import { ClientSecureChannelLayer, ConnectionStrategy, ConnectionStrategyOptions, SecurityPolicy } from "node-opcua-secure-channel"; import { FindServersOnNetworkRequestOptions, FindServersRequestOptions, ServerOnNetwork } from "node-opcua-service-discovery"; import { ApplicationDescription, EndpointDescription } from "node-opcua-service-endpoints"; import { ChannelSecurityToken, MessageSecurityMode } from "node-opcua-service-secure-channel"; import { ErrorCallback } from "node-opcua-status-code"; import { ResponseCallback } from "node-opcua-pseudo-session"; import { Request, Response } from "./common"; export type FindServersRequestLike = FindServersRequestOptions; export type FindServersOnNetworkRequestLike = FindServersOnNetworkRequestOptions; export type CreateSecureChannelCallbackFunc = (err: Error | null, secureChannel?: ClientSecureChannelLayer) => void; export interface FindEndpointOptions { securityMode: MessageSecurityMode; securityPolicy: SecurityPolicy; connectionStrategy: ConnectionStrategyOptions; certificateFile: string; privateKeyFile: string; applicationName: string; applicationUri: string; clientCertificateManager: OPCUACertificateManager; } export interface FindEndpointResult { selectedEndpoint: EndpointDescription; endpoints: EndpointDescription[]; } export type FindEndpointCallback = (err: Error | null, result?: FindEndpointResult) => void; export interface TransportSettings { maxChunkCount?: number; maxMessageSize?: number; sendBufferSize?: number; receiveBufferSize?: number; } export interface OPCUAClientBaseOptions { /** * the client application name * @default "NodeOPCUA-Client" */ applicationName?: string; /** * the application Uri * @default: `urn:${hostname}:${applicationName}` */ applicationUri?: string; connectionStrategy?: ConnectionStrategyOptions; /** * if not specify or set to 0 , token renewal will happen * around 75% of the defaultSecureTokenLifetime */ tokenRenewalInterval?: number; /** * if set to true, pending session will not be automatically closed when disconnect is called */ keepPendingSessionsOnDisconnect?: boolean; /** * the server certificate. */ serverCertificate?: Certificate; /** * default secure token lifetime in ms */ defaultSecureTokenLifetime?: number; /** * the security mode * @default MessageSecurityMode.None */ securityMode?: MessageSecurityMode | string; /** * the security policy * @default SecurityPolicy.None */ securityPolicy?: SecurityPolicy | string; /** * When set to true, the session will send a Read request on a regular interval specified by the `keepAliveInterval`. * * This ensure that the connection will remain active and that the socket will not timeout. * * When the keepAlive manager is not able to perform the Read operation, then it breaks the connection * and force the client to enter a reconnection phase. * * On some network settings and operating system, it might be quite tricky to detect when the communication * as the the * * * Tips: * * You don't ned to use `keepSessionAlive: true` when your session have a subscription active. * A OPCUA subscription has already a built-in keepAlive mechanism that can replace the regular Read pooling * offered by this flag. * * @default false */ keepSessionAlive?: boolean; /** * The number of milliseconds that the client should wait until it sends a keep alive message to the server. * * If not specified, node-opcua will use a suitable default value. * * Tips: * * - make sure to tune the value appropriately to be lesser than the sessionTimeOut and the tcp.ip socket * timeout. */ keepAliveInterval?: number; /** * The certificate Manager * * If not specified your Client will create and use a default Certificate manager. * * You will have pass your own OPCUACertificateManager if you are in one of the following situation: * * - you want to control the location of your PKI * - you want multiple instances of OPCUAClient to share the same OPCUACertificateManager * */ clientCertificateManager?: OPCUACertificateManager; /** * The client certificate pem file. * * Note: * - most of the time, you won't need to overload the certificate PEM fiel * - don't specify the certificateFile if you are using the PushCertificate built-in feature * provided by NodeOPCUA as it may interfere. * * @default `${clientCertificateManager/rootFolder}/own/certs/client_certificate.pem" */ certificateFile?: string; /** * client private key pem file. * Note: * - most of the time, you won't need to overload the private key file * - don't specify the privateKeyFile if you are using the PushCertificate built-in feature * provided by NodeOPCUA as it may interfere. * - ensure that the provided client certificate matches the private pey. * * @default `${clientCertificateManager/rootFolder}/own/private/private_key.pem" */ privateKeyFile?: string; /** * a client name string that will be used to generate session names. */ clientName?: string; /** * discovery url: */ discoveryUrl?: string; /** * specify some transport settings that will override * the default transport settings for the end point. */ transportSettings?: TransportSettings; /** * transport timeout * * - the devffault * @default */ transportTimeout?: number; /** * defaultTransactionTimeout */ defaultTransactionTimeout?: number; } export interface GetEndpointsOptions { endpointUrl?: string; localeIds?: LocaleId[]; profileUris?: string[]; } export interface OPCUAClientBase extends OPCUASecureObject { /** * certificate Manager */ readonly clientCertificateManager: OPCUACertificateManager; /*** * * @param endpointUrl the endpoint of the server to connect to ( i.e "opc.tcp://machine.name:3434/name" ) */ connect(endpointUrl: string): Promise<void>; connect(endpointUrl: string, callback: ErrorCallback): void; /*** * causes the client to close and disconnect the communication with server * * ### note * > once the client has disconnected, it cannot reconnect to the server * you'll need to recreate a new Client object to reconnect to the server. */ disconnect(): Promise<void>; disconnect(callback: ErrorCallback): void; findEndpointForSecurity(securityMode: MessageSecurityMode, securityPolicy: SecurityPolicy): EndpointDescription | undefined; getEndpoints(options?: GetEndpointsOptions): Promise<EndpointDescription[]>; getEndpoints(options: GetEndpointsOptions, callback: ResponseCallback<EndpointDescription[]>): void; getEndpoints(callback: ResponseCallback<EndpointDescription[]>): void; findServers(options?: FindServersRequestLike): Promise<ApplicationDescription[]>; findServers(options: FindServersRequestLike, callback: ResponseCallback<ApplicationDescription[]>): void; findServers(callback: ResponseCallback<ApplicationDescription[]>): void; findServersOnNetwork(options?: FindServersOnNetworkRequestLike): Promise<ServerOnNetwork[]>; findServersOnNetwork(callback: ResponseCallback<ServerOnNetwork[]>): void; findServersOnNetwork(options: FindServersOnNetworkRequestLike, callback: ResponseCallback<ServerOnNetwork[]>): void; } // Events ----------------------------------------------------------------------------- export interface OPCUAClientBase extends EventEmitter { // tslint:disable:unified-signatures /** * this Event is raised when the initial connection has succeeded */ on(eventName: "connected", eventHandler: () => void): this; /** * this Event is raised when the initial connection has failed */ on(eventName: "connection_failed", eventHandler: (err: Error) => void): this; /** * this Event is raised when a failing connection is about to be tried again */ on(eventName: "backoff", eventHandler: (count: number, delay: number) => void): this; /** * this event is raised when the client has encountered a connection failure and * and is going to reconnection mode. * * It notifies the observer that the OPCUA is now trying to reestablish the connection * after having received a connection break... * * You can intercept start_reconnection event to pause your interaction with the remote * OPCUA server. */ on(eventName: "start_reconnection", eventHandler: () => void): this; /** * this event is raised when the client has failed one attempt to reconnect to the server * This event will be raised if the socket has successfully being created to the server but * if something went wrong during the reconnection process. */ on(eventName: "reconnection_attempt_has_failed", eventHandler: (err: Error, message: string) => void): this; /** * this event is raised after the client has successfully managed to re-establish the connection with * the remote OPCUA Server. * You can intercept after_reconnection event to resume your interaction with the remote * OPCUA server. */ on(eventName: "after_reconnection", eventHandler: (err?: Error) => void): this; /** * the event is raised when the connection has been aborted by the remote OPCUA Server */ on(eventName: "abort", eventHandler: () => void): this; /** * this event is raised when the connection is closed */ on(eventName: "close", eventHandler: () => void): this; /** * this event is raised when the client is sending a message chunk to the server * (advanced use only) */ on(eventName: "send_chunk", eventHandler: (chunk: Buffer) => void): this; /** * this event is raised when the client has received a new message chunk from the servers * (advanced use only) */ on(eventName: "receive_chunk", eventHandler: (chunk: Buffer) => void): this; on(eventName: "send_request", eventHandler: (request: Request) => void): this; on(eventName: "receive_response", eventHandler: (response: Response) => void): this; /** * this event is raised when the current security token has reached 75% of its lifetime and is therefore * about to expired. */ on(eventName: "lifetime_75", eventHandler: (token: ChannelSecurityToken) => void): this; /** * this event is raised after the (about ) security token as been renewed * and renegotiated with the server.to expire */ on(eventName: "security_token_renewed", eventHandler: (channel: ClientSecureChannelLayer, token: ChannelSecurityToken) => void): this; /** * this event is raised when the connection has been broken */ on(eventName: "connection_lost", eventHandler: () => void): this; /** * this event is raised when a broken connection with the remote Server has been reestablished */ on(eventName: "connection_reestablished", eventHandler: () => void): this; /** * This event is raised when a request sent to the remote OPCUA server has reach it's timeout value without * a Response from the server. */ on(eventName: "timed_out_request", eventHandler: (request: Request) => void): this; on(eventName: string | symbol, listener: (...args: any[]) => void): this; } export interface OPCUAClientBase { readonly endpoint?: EndpointDescription; readonly isReconnecting: boolean; readonly transactionsPerformed: number; readonly knowsServerEndpoint: boolean; readonly reconnectOnFailure: boolean; readonly bytesRead: number; readonly bytesWritten: number; readonly securityMode: MessageSecurityMode; readonly securityPolicy: SecurityPolicy; readonly serverCertificate?: Certificate; readonly clientName: string; readonly protocolVersion: 0; readonly defaultSecureTokenLifetime: number; readonly tokenRenewalInterval: number; readonly connectionStrategy: ConnectionStrategy; readonly keepPendingSessionsOnDisconnect: boolean; readonly endpointUrl: string; readonly applicationName: string; } export class OPCUAClientBase { public static registry = new ObjectRegistry(); public static retryDelay = 1000 * 5; public static create(options: OPCUAClientBaseOptions): OPCUAClientBase { /* istanbul ignore next*/ options; throw new Error("Not Implemented"); } }