UNPKG

diffusion

Version:

Diffusion JavaScript client

396 lines (383 loc) 16.1 kB
var _interface = require('util/interface')._interface; /** * * Diffusion Session. Handles a connection to Diffusion and exposes API features. Sessions can subscribe, add, remove * and update topics, as well as perform remote operations on the server. * <P> * <br /> * A session represents a single connection to a single Diffusion server. A session begins connected and will remain * so until until it is explicitly closed via {@link Session#close} or there is a connection error. * <P> * When a connected session loses its connection to the server, it will close if {@link Session.Options} * <code>reconnect</code> is not enabled. If reconnect is enabled then the session will enter a * <code>disconnected</code> state. Once disconnected, any API methods that involve the server will automatically fail. * It is possible for a session to lose messages while disconnected. * <P> * The session will attempt to reconnect to the server on a regular basis. This will continue until the server responds; * at which point the session will attempt to recover its previous connection. * <P> * If the reconnection is succesful the session will become connected again and emit a <code>reconnect</code> event. * Any prior subscriptions will continue to receive data. * <P> * If the server rejects the reconnection, the session will be closed. * <P> * Sessions emit events to notify listeners of changes in state. Certain events will provide arguments to any callback * functions that have been registered. * * <H3>Session properties</H3> * <P> * For each session, the server stores a set of session properties that describe * various attributes of the session. * <P> * There are two types of session property. Fixed properties are assigned by the * server. User-defined properties are assigned by the application. * <> * Many operations use session filter expressions (see section Session Filters) * that use session properties to select sessions. * <P> * A privileged client can monitor other sessions, including changes to their * session properties, using a {@link * Session.clients#setSessionPropertiesListener session properties listener}. * When registering to receive session properties, special key values of {@link * diffusion.clients.PropertyKeys#ALL_FIXED_PROPERTIES ALL_FIXED_PROPERTIES} and * {@link diffusion.clients.PropertyKeys#ALL_USER_PROPERTIES * ALL_USER_PROPERTIES} can be used. * <P> * Each property is identified by a key. Most properties have a single string * value. The exception is the $Roles fixed property which has a set of string * values. * <P> * Fixed properties are identified by keys with a '$' prefix. The available * fixed session properties are: * <table border summary=""> * <tr> * <td><b>Key</b></td> * <td><b>Description</b></td> * <tr> * <tr> * <td>`$ClientIP`</td> * <td>The Internet address of the client in string format. See * {@link ClientLocation}.address.</td> * </tr> * <tr> * <td>`$ClientType`</td> * <td>The client type of the session. One of `ANDROID`, `C`, `DOTNET`, `IOS`, * `JAVA`, `JAVASCRIPT_BROWSER`, or `OTHER`. Equivalent to {@link * ClientSummary}.clientType.</td> * </tr> * <tr> * <td>`$Connector`</td> * <td>The configuration name of the server connector that the client connected * to. See {@link SessionDetails}.connector.</td> * </tr> * <tr> * <td>`$Country`</td> * <td>The country code for the country where the client's Internet address was * allocated (for example, `NZ` for New Zealand). If the country code could not * be determined, this will be a zero length string. See {@link * ClientLocation}.details.country.</td> * </tr> * <tr> * <td>`$Language`</td> * <td>The language code for the official language of the country where the * client's Internet address was allocated (for example, `en` for English). If * the language could not be determined or is not applicable, this will be a * zero length string. See {@link ClientLocation}.details.language.</td> * </tr> * <tr> * <td>`$Latitude`</td> * <td>The client's latitude, if available. This will be the string * representation of a floating point number and will be `NaN` if not * available. See {@link ClientLocation}.coordinates.latitude.</td> * </tr> * <tr> * <td>`$Longitude`</td> * <td>The client's longitude, if available. This will be the string * representation of a floating point number and will be `NaN` if not * available. See {@link ClientLocation}.coordinates.longitude.</td> * </tr> * <tr> * <td>`$Principal`</td> * <td>The security principal associated with the client session. Equivalent to * {@link ClientSummary}.principal</td> * </tr> * <tr> * <td>`$Roles`</td> * <td>Authorisation roles assigned to the session. This is a set of roles * represented as quoted strings (for example, `"role1","role2"`). The * utility method {@link diffusion#stringToRoles} can be used to parse * the string value into a set of roles.</td> * </tr> * <tr> * <td>`$ServerName`</td> * <td>The name of the server to which the session is connected. See * {@link SessionDetails}.server.</td> * </tr> * <tr> * <td>`$SessionId`</td> * <td>The session identifier. Equivalent to {@link Session.sessionID}.</td> * </tr> * <tr> * <td>`$StartTime`</td> * <td>The session's start time in milliseconds since the epoch.</td> * </tr> * <tr> * <td>`$Transport`</td> * <td>The session transport type. One of `WEBSOCKET`, * `HTTP_LONG_POLL`, or `OTHER`. Equivalent to * {@link ClientSummary}.transportType.</td> * </tr> * </table> * <p> * All user-defined property keys must be alphanumeric, starting with an * alphabetic character, and are case sensitive. Embedded whitespace is not * allowed. * <p> * Session properties are initially associated with a session as follows:<br> * <ol> * <li>When a client starts a new session, it can optionally propose * user-defined session properties (see {@link Session.Options}.properties). * Session properties proposed in this way must be accepted by the * authenticator. This safeguard prevents abuse by a rogue, unprivileged client. * <li>The server allocates all fixed property values. * <li>The new session is authenticated by registered authenticators. An * authenticator that accepts a session can veto or change the user-defined * session properties and add new user-defined session properties. The * authenticator can also change certain fixed properties. * </ol> * <P> * Once a session is established, its user-defined session properties can be * modified by clients with `VIEW_SESSION` and `MODIFY_SESSION` * permissions using {@link ClientControl#setSessionProperties}. * A privileged client can also modify its own session properties. * <P> * If a session re-authenticates (see * {@link Security#changePrincipal changePrincipal}), the * authenticator that allows the re-authentication can modify the user-defined * session properties and a subset of the fixed properties as mentioned above. * <H3>Session filters</H3> * <p> * Session filters are query expressions for session properties. They can be * used to address a set of sessions based on their session properties. For * example, it is possible to send a message to all sessions that satisfy a * specified filter. Session filters are parsed and evaluated at the server. * <P> * A session filter expression consists of either a single clause, or multiple * clauses connected by the binary operators `and` and `or`. The * `and` operator takes precedence over `or` but parentheses can be * used to override the precedence. For example: * * `Department is "Accounts"` * * `hasRoles ["operator" "trading desk"]` * * `Department is "Payroll" and Status is "Closed"}` * * `(Department is "Accounts" or Department is "Payroll") and Status is "Closed"}` * * <P> * The boolean <b>not</b> operator may be used to negate the following clause or * an expression within parentheses: * * `not Department is "Payroll"` * * `not (Department is "Payroll" or Department is "Accounts")` * * <P> * An equality clause has the form <em>key operator value</em> where * <em>key</em> is the name of a session property and <em>value</em> is the * property value. The supported operators are `is` or `eq`, both of * which mean "equals", and `ne` which means "does not equal". Values are * strings enclosed within single or double quotes. Special characters * (`"`, `'` or `\`) can be included within the value by * preceding with the escape character `\`. The utility method * {@link diffusion#escape} can be used to insert escape characters into * a value. * <p> * `hasRoles` is a special operator for querying the `$Roles` * session property. A `hasRoles` clause has the form <em>hasRoles * ["role1" "role2" ... "roleN"]</em>. The clause will match sessions that have * all the specified authorisation roles. Each role is a string enclosed within * either single or double quotes. Roles can be space or comma separated. * <p> * The `$Roles` session property can also be queried with an equality * clause, for example, `$Roles eq '"admin","client"'`, but the * `hasRoles` clause is usually more convenient. An equality clause will * match sessions that have exactly the listed roles. In contrast, a * `hasRoles` clause will match any sessions with the listed roles, * regardless of whether they have other roles. The equality clause requires the * value to be in the canonical form produced by the * {@link diffusion#rolesToString} utility method. * Supported operators are as follows: * <P> * <table border summary=""> * <tr> * <td><b>Operator</b></td> * <td><b>Description</b></td> * </tr> * <tr> * <td><b>is</b> or <b>eq</b></td> * <td>equals</td> * </tr> * <tr> * <td><b>ne</b></td> * <td>not equals</td> * </tr> * </table> * <P> * All operators are case insensitive. * <P> * The following are examples of valid expressions: * <P> * * `$Principal is "Alice"` * * `Department is "Accounts" and $Country ne "US"` * * `$Language EQ "en" and $Country NE "US"` * * `not (Department is "Accounts" or` * * `"Department is "Payroll") and $Country is "FR"` * * `Text is "xyz\"\\"` * * `hasRoles ["operator"]}` * * `$Transport is "wss" and hasRoles ["accountancy" "administrator"]` * * `hasRoles ["operator"] and not hasRoles ["administrator"]` * * @example * // Establish a session * diffusion.connect('diffusion.example.com').then(function(session) { * // Attach state listeners * session.on({ * disconnect : function() { * console.log('Disconnected!'); * }, * reconnect : function() { * console.log('Phew, reconnected!'); * }, * error : function(error) { * console.log('Session error', error); * }, * close : function(reason) { * console.log('Session closed', reason); * } * }); * * // Do something with session... * }); * * * @class Session * * @fires Session#disconnect * @fires Session#reconnect * @fires Session#error * @fires Session#close * * @property {Session.security} security - Exposes system authentication capabilities via a {@link Session.security}. * @property {Session.topics} topics - Exposes topic control capabilities via {@link Session.topics}. * @property {Session.topicUpdate} topicUpdate - Exposes topic update capabilities via {@link Session.topicUpdate}. * @property {Session.messages} messages - Exposes messaging capabilities via {@link Session.messages}. * @property {Session.notifications} notifications - Exposes topic notification capabilities via * {@link Session.notifications}. * @property {Session.clients} clients - Exposes client control capabilities via {@link Session.clients}. * @property {Session.Options} options - The options used when connecting. * @property {String} sessionID - The unique id assigned to this session by the server. * * @augments Stream */ module.exports = _interface('Session', [ /** * @property {SessionId} sessionID - The unique id assigned to this session by the server. */ 'sessionID', /** * @property {Options} options - The connection options used to establish this session */ 'options', /** * Close this session's connection to the server. * <P> * Calling this repeatedly will have no effect. * * @function Session#close * @return {Session} This session */ 'close', /** * Indicates if this session is currently closed, or in the process of * closing. * <P> * This will not return <code>true</code> if the session is disconnected * but attempting to reconnect. * * @function Session#isClosed * @return {boolean} Whether the session is currently closed. */ 'isClosed', /** * Indicates if this session is currently connected. * <P> * This is orthogonal to {@link Session#isClosed}, as a session may * be disconnected and attempting to reconnect. * * @function Session#isConnected * @return {boolean} Whether the session is currently connected or not. */ 'isConnected', /** * Returns the principal name that this session is associated with. * * @function Session#getPrincipal * @return {String} The principal for this session */ 'getPrincipal', /** * Attempt to acquire a {@link SessionLock session lock}. * <P> * This method returns a Promise that will resolve normally if * the server assigns the requested lock to the session. Otherwise, the * Promise will fail with an error indicating why the lock could not * be acquired. * * @function Session#lock * @param {String} lockName the name of the session lock * @param {diffusion.locks.SessionLockScope} scope (optional) preferred scope, defaults to * <code>UNLOCK_ON_SESSION_LOSS</code>. The scope of * a lock controls when it will be released automatically. If a * session makes multiple requests for a lock using different scopes, * and the server assigns the lock to the session fulfilling the * requests, the lock will be given the weakest scope * (<code>UNLOCK_ON_SESSION_LOSS</code>). * @return a Promise that resolves when a response is received * from the server. * * <p> * If this session has successfully acquired the session lock, or * this session already owns the session lock, the Promise * will resolve normally with a SessionLock result. * * <p> * If the Promise resolves with an error, this session * does not own the session lock. * @since 6.2 */ 'lock' /** * Emitted when a connected session has lost connection to the server, and {@link Session.Options} * <code>reconnect</code> is enabled. The provided reason will contain the specific cause of the * session disconnect. * * @event Session#disconnect * @property {diffusion.clients.CloseReason} reason - the cause of the session disconnect. */ /** * Emitted when a disconnected session has successfully reconnected. * @event Session#reconnect */ /** * Emitted when a session error has occurred. A session error occurs when * the client cannot parse communication from the server. This occurs if a component * between the two - for example, a proxy or load balancer - alters the communication. * * @event Session#error * @property {Error} error - the error that occured. */ /** * Emitted when a session is closed. This can occur because it was closed by the user, closed by the server, failed * to connect, or the session encountered an error. The provided close reason will contain the specific cause of the * session close. * * @event Session#close * @property {diffusion.clients.CloseReason} reason - the cause of the session close. */ ]);