in device/core/src/module_client.ts [45:118]
constructor(transport: DeviceTransport, methodClient: MethodClient) {
super(transport, undefined);
this._userRegisteredInputMessageListener = false;
this._methodClient = methodClient;
/* Codes_SRS_NODE_MODULE_CLIENT_18_012: [ The `inputMessage` event shall be emitted when an inputMessage is received from the IoT Hub service. ]*/
/* Codes_SRS_NODE_MODULE_CLIENT_18_013: [ The `inputMessage` event parameters shall be the inputName for the message and a `Message` object. ]*/
this._transport.on('inputMessage', (inputName, msg) => {
this.emit('inputMessage', inputName, msg);
});
this.on('removeListener', () => {
if (this.listenerCount('inputMessage') === 0) {
this._userRegisteredInputMessageListener = false;
/* Codes_SRS_NODE_MODULE_CLIENT_18_015: [ The client shall stop listening for messages from the service whenever the last listener unsubscribes from the `inputMessage` event. ]*/
debug('in removeListener, disabling input messages');
this._disableInputMessages((err) => {
if (err) {
debugErrors('in removeListener, error disabling input messages: ' + err);
this.emit('error', err);
} else {
debug('removeListener successfully disabled input messages.');
}
});
}
});
this.on('newListener', (eventName) => {
if (eventName === 'inputMessage') {
//
// We want to always retain that the we want to have this feature enabled because the API (.on) doesn't really
// provide for the capability to say it failed. It can certainly fail because a network operation is required to
// enable.
// By saving this off, we are strictly honoring that the feature is enabled. If it doesn't turn on we signal via
// the emitted 'error' that something bad happened.
// But if we ever again attain a connected state, this feature will be operational.
//
this._userRegisteredInputMessageListener = true;
/* Codes_SRS_NODE_MODULE_CLIENT_18_014: [ The client shall start listening for messages from the service whenever there is a listener subscribed to the `inputMessage` event. ]*/
debug('in newListener, enabling input messages');
this._enableInputMessages((err) => {
if (err) {
debugErrors('in newListener, error enabling input messages: ' + err);
this.emit('error', err);
} else {
debug('in newListener, successfully enabled input messages');
}
});
}
});
this._moduleDisconnectHandler = (err) => {
if (err) {
debugErrors('transport disconnect event: ' + err);
} else {
debug('transport disconnect event: no error');
}
if (err && this._retryPolicy.shouldRetry(err)) {
if (this._userRegisteredInputMessageListener) {
debug('re-enabling input message link');
this._enableInputMessages((err) => {
if (err) {
debugErrors('Error re-enabling input messages: ' + err);
/*Codes_SRS_NODE_MODULE_CLIENT_16_102: [If the retry policy fails to reestablish the C2D functionality a `disconnect` event shall be emitted with a `results.Disconnected` object.]*/
this.emit('disconnect', new results.Disconnected(err));
}
});
}
}
};
/*Codes_SRS_NODE_MODULE_CLIENT_16_045: [If the transport successfully establishes a connection the `open` method shall subscribe to the `disconnect` event of the transport.]*/
this._transport.on('disconnect', this._moduleDisconnectHandler);
}