UNPKG

node-opcua-client

Version:

pure nodejs OPCUA SDK - module client

117 lines 6.11 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.republish = republish; const util_1 = require("util"); const async_1 = __importDefault(require("async")); const chalk_1 = __importDefault(require("chalk")); const node_opcua_assert_1 = __importDefault(require("node-opcua-assert")); const node_opcua_debug_1 = require("node-opcua-debug"); const node_opcua_status_code_1 = require("node-opcua-status-code"); const node_opcua_types_1 = require("node-opcua-types"); const client_subscription_reconnection_1 = require("./client_subscription_reconnection"); const reconnection_1 = require("./reconnection"); const debugLog = (0, node_opcua_debug_1.make_debugLog)("RECONNECTION"); const doDebug = (0, node_opcua_debug_1.checkDebugFlag)("RECONNECTION"); function _republish(engine, subscription, callback) { let isDone = false; const session = engine.session; const sendRepublishFunc = (callback2) => { (0, node_opcua_assert_1.default)(isFinite(subscription.lastSequenceNumber) && subscription.lastSequenceNumber + 1 >= 0); const request = new node_opcua_types_1.RepublishRequest({ retransmitSequenceNumber: subscription.lastSequenceNumber + 1, subscriptionId: subscription.subscriptionId }); // istanbul ignore next if (doDebug) { // istanbul ignore next debugLog(chalk_1.default.bgCyan.yellow.bold(" republish Request for subscription"), request.subscriptionId, " retransmitSequenceNumber=", request.retransmitSequenceNumber); } if (!session || session._closeEventHasBeenEmitted) { debugLog("ClientPublishEngine#_republish aborted "); // has client been disconnected in the mean time ? isDone = true; return callback2(); } session.republish(request, (err, response) => { const statusCode = err ? node_opcua_status_code_1.StatusCodes.Bad : response.responseHeader.serviceResult; if (!err && (statusCode.equals(node_opcua_status_code_1.StatusCodes.Good) || statusCode.equals(node_opcua_status_code_1.StatusCodes.BadMessageNotAvailable))) { // reprocess notification message and keep going if (statusCode.equals(node_opcua_status_code_1.StatusCodes.Good)) { subscription.onNotificationMessage(response.notificationMessage); } } else { if (!err) { err = new Error(response.responseHeader.serviceResult.toString()); } debugLog(" _send_republish ends with ", err.message); isDone = true; } callback2(err ? err : undefined); }); }; const sendRepublishUntilDone = () => { async_1.default.whilst((cb) => cb(null, !isDone), sendRepublishFunc, ((err) => { debugLog("nbPendingPublishRequest = ", engine.nbPendingPublishRequests); debugLog(" _republish ends with ", err ? err.message : "null"); callback(err); }) // Wait for @type/async bug to be fixed ! ); }; setImmediate(sendRepublishUntilDone); } function __askSubscriptionRepublish(engine, subscription, callback) { _republish(engine, subscription, (err) => { // prettier-ignore { const _err = (0, reconnection_1._shouldNotContinue2)(subscription); if (_err) { return callback(_err); } } (0, node_opcua_assert_1.default)(!err || util_1.types.isNativeError(err)); debugLog("__askSubscriptionRepublish--------------------- err =", err ? err.message : null); if (err && err.message.match(/BadSessionInvalid/)) { // _republish failed because session is not valid anymore on server side. return callback(err); } if (err && err.message.match(/SubscriptionIdInvalid/)) { // _republish failed because subscriptionId is not valid anymore on server side. // // This could happen when the subscription has timed out and has been deleted by server // Subscription may time out if the duration of the connection break exceed the max life time // of the subscription. // // In this case, Client must recreate a subscription and recreate monitored item without altering // the event handlers // debugLog(chalk_1.default.bgWhite.red("__askSubscriptionRepublish failed " + " subscriptionId is not valid anymore on server side.")); return (0, client_subscription_reconnection_1.recreateSubscriptionAndMonitoredItem)(subscription).then(() => callback()).catch(err => callback(err)); } if (err && err.message.match(/|MessageNotAvailable/)) { // start engine and start monitoring } callback(); }); } function republish(engine, callback) { // After re-establishing the connection the Client shall call Republish in a loop, starting with // the next expected sequence number and incrementing the sequence number until the Server returns // the status BadMessageNotAvailable. // After receiving this status, the Client shall start sending Publish requests with the normal Publish // handling. // This sequence ensures that the lost NotificationMessages queued in the Server are not overwritten // by newPublish responses /** * call Republish continuously until all Notification messages of * un-acknowledged notifications are reprocessed. */ const askSubscriptionRepublish = (subscription, subscriptionId, innerCallback) => { __askSubscriptionRepublish(engine, subscription, innerCallback); }; async_1.default.forEachOf(engine.subscriptionMap, askSubscriptionRepublish, callback); } //# sourceMappingURL=client_publish_engine_reconnection.js.map