/* AeroGear JavaScript Library
* https://github.com/aerogear/aerogear-js
* JBoss, Home of Professional Open Source
* Copyright Red Hat, Inc., and individual contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
The mqttws adapter uses MQTT over WebSockets for messaging.
@deprecated since 2.1.0 and will be removed in a future release.
@status Deprecated
@constructs AeroGear.Notifier.adapters.mqttws
@param {String} clientName - The name used to reference this particular notifier client
@param {Object} [settings={}] - The settings to be passed to the adapter
@param {Boolean} [settings.autoConnect=false] - Automatically connect the client to the connectURL on creation. This option is ignored and a connection is automatically established if channels are provided as the connection is necessary prior to channel subscription
@param {String} [settings.connectURL=""] - Defines the URL for connecting to the messaging service
@param {Function} [settings.onConnect] - Callback to be executed when a connection is established if autoConnect === true
@param {Function} [settings.onConnectError] - Callback to be executed when connecting to a service is unsuccessful if autoConnect === true
@param {Function} [settings.onMessage] - Callback to be executed when a message is received
@param {Array} [settings.channels=[]] - A set of channel objects to which this client can subscribe. Each object should have a String address
@returns {Object} The created notifier client
@example
// Create an empty Notifier
var notifier = AeroGear.Notifier();
// Create a channel object and the channel callback function
var channelObject = {
address: "org.aerogear.messaging.global"
};
// Add an mqttws client with all the settings
notifier.add({
name: "client1",
settings: {
autoConnect: true,
connectURL: window.location.protocol + '//' + window.location.host + "/eventbus",
onConnect: function() {
console.log( "connected" );
},
onConnectError: function() {
console.log( "connection error" );
},
onMessage: function ( message ) {
console.log( message.destinationName + " " + message.payloadString );
},
channels: [ channelObject ]
}
});
*/
AeroGear.Notifier.adapters.mqttws = function( clientName, settings ) {
// Allow instantiation without using new
if ( !( this instanceof AeroGear.Notifier.adapters.mqttws ) ) {
return new AeroGear.Notifier.adapters.mqttws( clientName, settings );
}
settings = settings || {};
AeroGear.Notifier.adapters.base.apply( this, arguments );
// Private Instance vars
var type = "mqttws",
clientId = settings.clientId || "agClientId";
// Privileged methods
/**
Returns the value of the private clientId var
@private
@augments mqttws
*/
this.getClientId = function() {
return clientId;
};
/**
Set the value of the private clientId var
@private
@augments mqttws
@param {String} id - New clientId for this client
*/
this.setClientId = function( id ) {
clientId = id;
};
/**
Process the connect options
@param {Object} connectOptions - The connect options to process
@private
@augments mqttws
*/
this.processConnectOptions = function( connectOptions ) {
if ( connectOptions.onConnect ) {
connectOptions.onSuccess = connectOptions.onConnect;
delete connectOptions.onConnect;
}
if ( connectOptions.onConnectError ) {
connectOptions.onFailure = connectOptions.onConnectError;
delete connectOptions.onConnectError;
}
if ( connectOptions.login ) {
connectOptions.userName = connectOptions.login;
delete connectOptions.login;
}
if ( connectOptions.url ) {
delete connectOptions.url;
}
if ( connectOptions.clientId ) {
delete connectOptions.clientId;
}
if ( connectOptions.onMessage ) {
delete connectOptions.onMessage;
}
return connectOptions;
};
/**
Process a URL
@param {String} url - The url to process
@private
@augments mqttws
*/
this.processURL = function ( url ) {
var processedURL = {},
urlParts = url.split( '/' ),
protocol = urlParts[ 0 ].split( ':' )[ 0 ],
domainParts = urlParts[ 2 ].split( ':' ),
// default path is /mqtt
path = "/" + ( urlParts[ 3 ] || "mqtt" );
processedURL.hostname = domainParts[ 0 ];
processedURL.port = Number( domainParts[ 1 ] ) || ( protocol === 'wss' ? 443 : 80 );
processedURL.path = path;
return processedURL;
};
};
//Public Methods
/**
Connect the client to the messaging service
@param {Object} [options={}] - Options to pass to the connect method
@param {String} [options.url] - The URL for the messaging service. This url will override and reset any connectURL specified when the client was created
@param {Number} [options.mqttVersion] - The MQTT protocol version. Should be 3 or 4.
@param {Number} [options.timeout] - If the connect has not succeeded within this number of seconds, it is deemed to have failed
@param {String} [options.login] - Authentication login name for this connection
@param {String} [options.password] - Authentication password for this connection
@param {Number} [options.keepAliveInterval] - The server disconnects this client if there is no activity for this number of seconds
@param {Messaging.Message} [options.willMessage] - Sent by the server when the client disconnects abnormally
@param {Boolean} [options.cleanSession] - If true(default) the client and server persistent state is deleted on successful connect
@param {Boolean} [options.useSSL] - If present and true, use an SSL Websocket connection
@param {Function} [options.onConnect] - Callback to be executed when a connection is established
@param {Function} [options.onConnectError] - Callback to be executed when connecting to a service is unsuccessful
@param {Function} [settings.onMessage] - Callback to be executed when a message is received
@example
// Create an empty Notifier
var notifier = AeroGear.Notifier();
// Add an mqtt client
notifier.add({
name: "client1",
settings: {
connectURL: window.location.protocol + '//' + window.location.host + "/eventbus",
onConnect: function() {
console.log( "connected" );
},
onConnectError: function() {
console.log( "connection error" );
},
onMessage: function ( message ) {
console.log( message.destinationName + " " + message.payloadString );
}
}
});
// Connect to the vertx messaging service
notifier.clients.client1.connect();
*/
AeroGear.Notifier.adapters.mqttws.prototype.connect = function( options ) {
options = options || {};
var that = this,
onConnectCallback = options.onConnect,
onConnectErrorCallback = options.onConnectError,
client, onConnect, onConnectError, processedURL;
processedURL = this.processURL( options.url || this.getConnectURL() );
client = new Paho.MQTT.Client( processedURL.hostname, processedURL.port, processedURL.path, options.clientId || this.getClientId() );
if ( options.onMessage ) {
client.onMessageArrived = options.onMessage;
}
options.onConnect = function() {
// Make a Copy of the channel array instead of a reference.
var channels = that.getChannels().slice( 0 );
that.setState( AeroGear.Notifier.CONNECTED );
that.subscribe( channels, true );
if ( onConnectCallback ) {
onConnectCallback.apply( this, arguments );
}
};
options.onConnectError = function() {
that.setState( AeroGear.Notifier.DISCONNECTED );
if ( onConnectErrorCallback ) {
onConnectErrorCallback.apply( this, arguments );
}
};
client.connect( this.processConnectOptions( options ) );
this.setClient( client );
};
/**
Disconnect the client from the messaging service
@example
// Create an empty Notifier
var notifier = AeroGear.Notifier();
// Add an mqtt client
notifier.add({
name: "client1",
settings: {
connectURL: window.location.protocol + '//' + window.location.host + "/eventbus",
onConnect: function() {
console.log( "connected" );
},
onConnectError: function() {
console.log( "connection error" );
},
onMessage: function( message ) {
console.log( message.destinationName + " " + message.payloadString );
}
}
});
// Connect to the vertx messaging service
notifier.clients.client1.connect();
// Disconnect from the vertx messaging service
notifier.clients.client1.disconnect();
*/
AeroGear.Notifier.adapters.mqttws.prototype.disconnect = function() {
var client = this.getClient();
if ( this.getState() === AeroGear.Notifier.CONNECTED ) {
this.setState( AeroGear.Notifier.DISCONNECTING );
client.disconnect();
}
};
/**
Subscribe this client to a new channel
@param {Object|Array} channels - A channel object or array of channel objects to which this client can subscribe. Each object should have a String address as well as an optional subscribeOptions object which is used to control the subscription
@param {Boolean} [reset] - If true, remove all channels from the set and replace with the supplied channel(s)
@example
// Create an empty Notifier
var notifier = AeroGear.Notifier();
// Create a channel object and the channel callback function
var channelObject = {
address: "org.aerogear.messaging.global",
subscribeOptions: {
qos: 2,
onSuccess: function() {
console.log( 'Subscription was successful' );
},
onFailure: function() {
console.log( 'Subscription failed' );
},
timeout: 60
}
};
// Add a mqtt client with autoConnect === true and no channels
notifier.add({
name: "client1",
settings: {
autoConnect: true,
connectURL: window.location.protocol + '//' + window.location.host + "/eventbus",
onConnect: function() {
console.log( "connected" );
},
onConnectError: function() {
console.log( "connection error" );
},
onMessage: function( message ) {
console.log( message.destinationName + " " + message.payloadString );
}
}
});
// Subscribe to a channel
notifier.clients.client1.subscribe( channelObject );
// Subscribe to multiple channels at once
notifier.clients.client1.subscribe([
{
address: "newChannel",
subscribeOptions: {...}
},
{
address: "anotherChannel",
subscribeOptions: { ... }
}
]);
// Subscribe to a channel, but first unsubscribe from all currently subscribed channels by adding the reset parameter
notifier.clients.client1.subscribe({
address: "newChannel",
subscribeOptions: { ... }
}, true );
*/
AeroGear.Notifier.adapters.mqttws.prototype.subscribe = function( channels, reset ) {
var client = this.getClient();
if ( reset ) {
this.unsubscribe( this.getChannels() );
}
channels = Array.isArray( channels ) ? channels : [ channels ];
for ( var i = 0; i < channels.length; i++ ) {
this.addChannel( channels[ i ] );
client.subscribe( channels[ i ].address, channels[ i ].subscribeOptions || {} );
}
};
/**
Unsubscribe this client from a channel
@param {Object|Array} channels - A channel object or a set of channel objects to which this client nolonger wishes to subscribe. Each object should have a String address and an optional unsubscribeOptions object
@example
// Unsubscribe from a previously subscribed channel
notifier.clients.client1.unsubscribe(
{
address: "org.aerogear.messaging.global",
unsubscribeOptions: {
onSuccess: function() {
console.log( 'Unusubscribe was successful' );
},
onFailure: function() {
console.log( 'Unsubscribe failed' );
},
timeout: 20
}
}
);
// Unsubscribe from multiple channels
notifier.clients.client1.unsubscribe([
{
address: "newChannel",
unsubscribeOptions: { ... }
},
{
address: "anotherChannel"
}
]);
*/
AeroGear.Notifier.adapters.mqttws.prototype.unsubscribe = function( channels ) {
var client = this.getClient();
channels = Array.isArray( channels ) ? channels : [ channels ];
for ( var i = 0; i < channels.length; i++ ) {
client.unsubscribe( channels[ i ].address, channels[ i ].unsubscribeOptions || {} );
this.removeChannel( channels[ i ] );
}
};
/**
Send a message to a particular channel
@param {String} channel - The channel to which to send the message
@param {String|Object} [message=""] - The message object to send
@param {Object} [sendOptions] - The send options to send
@example
// Send an empty message to a channel
notifier.clients.client1.send( "test.address" );
// Send a "Hello" message to a channel
notifier.clients.client1.send( "test.address", "Hello" );
*/
AeroGear.Notifier.adapters.mqttws.prototype.send = function( channel, message, sendOptions ) {
var client = this.getClient();
message = new Paho.MQTT.Message( message || "" );
message.destinationName = channel;
if ( sendOptions ) {
if ( sendOptions.qos ) {
message.qos = sendOptions.qos;
}
if ( sendOptions.retained ) {
message.retained = sendOptions.retained;
}
if ( sendOptions.duplicate ) {
message.duplicate = sendOptions.duplicate;
}
}
client.send( message );
};