new MatsSocket(appName, appVersion, urls, config)
Creates a MatsSocket, requiring the using Application's name and version, and which URLs to connect to.
Note: Public, Private and Privileged modelled after
http://crockford.com/javascript/private.html
Parameters:
Name | Type | Description |
---|---|---|
appName |
string | the name of the application using this MatsSocket.js client library |
appVersion |
string | the version of the application using this MatsSocket.js client library |
urls |
array | an array of WebSocket URLs speaking 'matssocket' protocol, or a single string URL. |
config |
object | an optional object carrying extra configuration. Current sole key: 'webSocketFactory': how to make WebSockets, not required in a browser setting as it will use window.WebSocket if not set. |
- Source:
Members
debug :number
A bit field requesting different types of debug information from the server - the flags/bits are defined in
DebugOption. The information concerns timings and which server nodes have handled the messages.
This field is used as the default for requests sent to the server, but individual requests may also set
the debug flags explicitly (i.e. override) by use of the optional "config" object on
MatsSocket#requestReplyTo or MatsSocket#request.
To facilitate debug information also on Server initiated messages, the last sent debug flags is
also stored on the server and used when messages originate there (i.e. Server-to-Client SENDs and REQUESTs).
This goes both if the default was used (this flag), or overridden-per-request config: The last flag sent over
is used for any subsequent server-initiated message. This is arguably a pretty annoying way to control the server
initiated debug flags - vote for Issue 13
if you want something more explicit.
The value is a bit field (values in DebugOption), so you bitwise-or (or simply add) together the
different things you want.
The value from the client is bitwise-and'ed together with the debug capabilities the authenticated user has
gotten by the AuthenticationPlugin on the Server side. This means that the AuthenticationPlugin ultimately
controls how much info the accessing user is allowed to get.
Default is
0
, i.e. no debug.
Type:
- number
- Source:
logging :boolean
Whether to log via console.log. The logging is quite extensive. Default
false
.
Type:
- boolean
- Source:
outofbandclose :function|boolean
"Out-of-band Close" refers to a small hack to notify the server about a MatsSocketSession being Closed even
if the WebSocket is not live anymore: When MatsSocket#close is invoked, an attempt is done to close
the WebSocket with CloseCode MatsSocketCloseCodes.CLOSE_SESSION - but whether the WebSocket is open
or not, this "Out-of-band Close" will also be invoked if enabled and MatsSocket SessionId is present.
Values:
- "Falsy", e.g.
false
: Disables this functionality - A
function
: The function is invoked when close(..) is invoked, the single parameter being an object with two keys:'webSocketUrl'
is the current WebSocket url, i.e. the URL that the WebSocket was connected to, e.g. "wss://example.com/matssocket".'sessionId'
is the current MatsSocket SessionId - the one we're trying to close. - "Truthy", e.g.
true
(default): When this MatsSocket library is used in a web browser context, the following code is executed:navigator.sendBeacon(webSocketUrl.replace('ws', 'http)+"/close_session?sessionId={sessionId}")
. Note that replace is replace-first, and that an extra 's' in 'wss' thus results in 'https'.
true
.
Note: A 'beforeunload' listener invoking MatsSocket#close is attached when running in a web browser,
so that if the user navigates away, the current MatsSocketSession is closed.
Type:
- function | boolean
- Source:
preconnectoperation :boolean|string|function
"Pre Connection Operation" refers to a hack whereby the MatsSocket performs a specified operation - by default
a XMLHttpRequest to the same URL as the WebSocket will be connected to - before initiating the
WebSocket connection. The goal of this solution is to overcome a deficiency with the WebSocket Web API
where it is impossible to add headers, in particular "Authorization": The XHR adds the Authorization header
as normal, and the server side can transfer this header value over to a Cookie (e.g. named "MatsSocketAuthCookie").
When the WebSocket connect is performed, the cookies will be transferred along with the initial "handshake"
HTTP Request - and the AuthenticationPlugin on the server side can then validate the Authorization header -
now present in a cookie. Note: One could of course have supplied it in the URL of the WebSocket HTTP Handshake,
but this is very far from ideal, as a live authentication then could be stored in several ACCESS LOG style
logging systems along the path of the WebSocket HTTP Handshake Request call.
Values:
- "Falsy", e.g.
false
(default): Disables this functionality. - A
string
: Performs aXMLHttpRequest
with the URL set to the specified string, with the HTTP Header "Authorization
" set to the current AuthorizationValue. Expects 200, 202 or 204 as returned status code to go on. - A
function
: Invokes the function with a parameter object containing'webSocketUrl'
, which is the current WebSocket URL that we will connect to when this PreConnectionOperation has gone through, and'authorization'
, which is the current Authorization Value. Expects a two-element array returned: [abortFunction, requestPromise]. The abortFunction is invoked when the connection-retry system deems the current attempt to have taken too long time. The requestPromise must be resolved by your code when the request has been successfully performed, or rejected if it didn't go through. In the latter case, a new invocation of the 'preconnectoperation' will be performed after a countdown, possibly with a different 'webSocketUrl' value if the MatsSocket is configured with multiple URLs. - "Truthy", e.g.
true
: Performs aXMLHttpRequest
to the same URL as the WebSocket URL, with "ws" replaced with "http", similar to MatsSocket#outofbandclose, and the HTTP Header "Authorization
" set to the current Authorization Value. Expects 200, 202 or 204 as returned status code to go on.
false
.
Note: For inspiration for the function-style value of this config, look in the source for the method
w_defaultXhrPromiseFactory(params)
.
Note: A WebSocket is set up with a single HTTP Request, called the "Upgrade" or "Handshake" request. The
point about being able to send Authorization along with the WebSocket connect only refers to this initial
HTTP Request. Subsequent updates of the Authorization by means of invocation of
MatsSocket#setCurrentAuthorization will not result in new HTTP calls - these new Authorization
strings are sent in-band with WebSocket messages (MatsSocket envelopes).
Type:
- boolean | string | function
- Source:
requestTimeout :number
When performing a Request and RequestReplyTo,
you may not always get a (timely) answer: Either you can lose the connection, thus lagging potentially forever -
or, depending on the Mats message handling on the server (i.e. using "non-persistent messaging" for blazing fast
performance for non-state changing operations), there is a minuscule chance that the message may be lost - or, if
there is a massive backlog of messages for the particular Mats endpoint that is interfaced, you might not get an
answer for 20 minutes. This setting controls the default timeout in milliseconds for Requests, and is default
45000 milliseconds (45 seconds), but you may override this per Request by specifying a different timeout in the
config object for the request. When the timeout is hit, the Promise of a MatsSocket#request - or the
specified ReplyTo Terminator for a MatsSocket#requestReplyTo - will be rejected with a
MessageEvent of type MessageEventType.TIMEOUT. In addition, if the Received acknowledgement has
not gotten in either, this will also (before the Promise reject!) be NACK'ed with
ReceivedEventType.TIMEOUT
Type:
- number
- Source:
(static, readonly) connected :string
Returns whether this MatsSocket currently have a WebSocket connection open. It can both go down
by lost connection (driving through a tunnel), where it will start to do reconnection attempts, or because
you (the Client) have closed this MatsSocketSession, or because the Server has
closed the MatsSocketSession.
Pretty much the same as
(MatsSocket.state === ConnectionState.CONNECTED)
|| (MatsSocket.state === ConnectionState.SESSION_ESTABLISHED)
- however, in the face of
MessageType.DISCONNECT, the state will not change, but the connection is dead ('connected' returns
false).
Type:
- string
- Source:
(static, readonly) lastMessageEnqueuedTimestamp :number
Millis-since-epoch of last message enqueued. This can be used by the mechanism invoking
MatsSocket#setCurrentAuthorization to decide whether it should keep the
authorization fresh (i.e. no latency waiting for new authorization is introduced when a new message is
enqueued), or fall back to relying on the 'authorizationExpiredCallback' being invoked when a new message needs
it (thus introducing latency while waiting for authorization). One could envision keeping fresh auth for 5
minutes, but if the user has not done anything requiring authentication (i.e. sending information bearing
messages SEND, REQUEST or Replies) in that timespan, you stop doing continuous authentication refresh, falling
back to the "on demand" based logic, where when a message is enqueued, the
MatsSocket#setAuthorizationExpiredCallback is invoked if the authentication is expired.
Type:
- number
- Source:
(static, readonly) state :string
Returns which one of the ConnectionState state enums the MatsSocket is in.
- NO_SESSION - initial state, and after Session Close (both from client and server side)
- CONNECTING - when we're actively trying to connect, i.e. "new WebSocket(..)" has been invoked, but not yet either opened or closed.
- WAITING - if the "new WebSocket(..)" invocation ended in the socket closing, i.e. connection failed, but we're still counting down to next (re)connection attempt.
- CONNECTED - if the "new WebSocket(..)" resulted in the socket opening. We still have not established the MatsSocketSession with the server, though.
- SESSION_ESTABLISHED - when we're open for business: Connected, authenticated, and established MatsSocketSession with the server.
Type:
- string
- Source:
Methods
addConnectionEventListener(connectionEventListener)
Note: You could register a ConnectionEvent listener, as these are only informational messages
about the state of the Connection. It is nice if the user gets a small notification about "Connection
Lost, trying to reconnect in 2 seconds" to keep him in the loop of why the application's data fetching
seems to be lagging. There are suggestions of how to approach this with each of the enum values of
ConnectionEventType.
The registered event listener functions are called when this client library performs WebSocket connection
operations, including connection closed events that are not "Session Close" style. This includes the simple
situation of "lost connection, reconnecting" because you passed through an area with limited or no
connectivity.
Read more at ConnectionEvent and ConnectionEventType.
Parameters:
Name | Type | Description |
---|---|---|
connectionEventListener |
connectionEventCallback | a function that is invoked when the library issues ConnectionEvents. |
- Source:
addErrorEventListener(errorEventListener)
Some 25 places within the MatsSocket client catches errors of different kinds, typically where listeners
cough up errors, or if the library catches mistakes with the protocol, or if the WebSocket emits an error.
Add a ErrorEvent listener to get hold of these, and send them back to your server for
inspection - it is best to do this via out-of-band means, e.g. via HTTP. For browsers, consider
navigator.sendBeacon(..)
.
The event object is ErrorEvent.
Parameters:
Name | Type | Description |
---|---|---|
errorEventListener |
errorEventCallback |
- Source:
addInitiationProcessedEventListener(initiationProcessedEventListener, includeInitiationMessage, includeReplyMessageEvent)
Registering an InitiationProcessedEvent listener will give you meta information about each Send
and Request that is performed through the library when it is fully processed, thus also containing
information about experienced round-trip times. The idea is that you thus can gather metrics of
performance as experienced out on the client, by e.g. periodically sending this gathering to the Server.
Make sure that you understand that if you send to the server each time this listener is invoked, using
the MatsSocket itself, you WILL end up in a tight loop! This is because the sending of the statistics
message itself will again trigger a new invocation of this listener. This can be avoided in two ways: Either
instead send periodically - in which case you can include the statistics message itself, OR specify that
you do NOT want a listener-invocation of these messages by use of the config object on the send, request
and requestReplyTo methods.
Note: Each listener gets its own instance of InitiationProcessedEvent, which also is different from
the ones in the MatsSocket.initiations array.
Parameters:
Name | Type | Description |
---|---|---|
initiationProcessedEventListener |
initiationProcessedEventCallback | a function that is invoked when the library issues InitiationProcessedEvents. |
includeInitiationMessage |
boolean | whether to include the InitiationProcessedEvent#initiationMessage |
includeReplyMessageEvent |
boolean | whether to include the InitiationProcessedEvent#replyMessageEvent Reply MessageEvents. |
- Source:
addPingPongListener(pingPongListener)
A PingPong listener is invoked each time a MessageType#PONG message comes in, giving you
information about the experienced round-trip time. The PINGs and PONGs are
handled slightly special in that they always are handled ASAP with short-path code routes, and should thus
give a good indication about experienced latency from the network. That said, they are sent on the same
connection as all data, so if there is a gigabyte document "in the pipe", the PING will come behind that
and thus get a big hit. Thus, you should consider this when interpreting the results - a high outlier should
be seen in conjunction with a message that was sent at the same time.
Parameters:
Name | Type | Description |
---|---|---|
pingPongListener |
addPingPongCallback | a function that is invoked when the library issues |
- Source:
addSessionClosedEventListener(sessionClosedEventListener)
Note: You should register a SessionClosedEvent listener, as any invocation of this listener by this
client library means that you've either not managed to do initial authentication, or lost sync with the
server, and you should crash or "reboot" the application employing the library to regain sync.
The registered event listener functions are called when the Server kicks us off the socket and the session is
closed due to a multitude of reasons, where most should never happen if you use the library correctly, in
particular wrt. authentication. It is NOT invoked when you explicitly invoke matsSocket.close() from
the client yourself!
The event object is the WebSocket's CloseEvent, adorned with properties 'codeName', giving the
key name of the MatsSocketCloseCodes (as provided by MatsSocketCloseCodes#nameFor),
and 'outstandingInitiations', giving the number of outstanding initiations when the session was closed.
You can use the 'code' to "enum-compare" to
MatsSocketCloseCodes
, the enum keys are listed here:
- UNEXPECTED_CONDITION: Error on the Server side, typically that the data store (DB) was unavailable, and the MatsSocketServer could not reliably recover the processing of your message.
- MATS_SOCKET_PROTOCOL_ERROR: This client library has a bug!
- VIOLATED_POLICY: Initial Authorization was wrong. Always supply a correct and non-expired Authorization value, which has sufficient 'roomForLatency' wrt. the expiry time.
- CLOSE_SESSION:
MatsSocketServer.closeSession(sessionId)
was invoked Server side for this MatsSocketSession - SESSION_LOST: A reconnect attempt was performed, but the MatsSocketSession was timed out on the Server. The Session will never time out if the WebSocket connection is open. Only if the Client has lost connection, the timer will start. The Session timeout is measured in hours or days. This could conceivably happen if you close the lid of a laptop, and open it again days later - but one would think that the Authentication session (the one giving you Authorization headers) had timed out long before.
Parameters:
Name | Type | Description |
---|---|---|
sessionClosedEventListener |
sessionClosedEventCallback | a function that is invoked when the library gets the current MatsSocketSession closed from the server. The event object is the WebSocket's CloseEvent. |
- Source:
addSubscriptionEventListener(subscriptionEventListener)
Note: If you use subscriptions, you should register a
SubscriptionEvent listener, as you should be concerned about SubscriptionEventType.NOT_AUTHORIZED
and SubscriptionEventType.LOST_MESSAGES.
Read more at SubscriptionEvent and SubscriptionEventType.
Parameters:
Name | Type | Description |
---|---|---|
subscriptionEventListener |
subscriptionEventCallback | a function that is invoked when the library gets information from the Server wrt. subscriptions. |
- Source:
close(reason)
Closes any currently open WebSocket with MatsSocket-specific CloseCode CLOSE_SESSION (4000). Depending
of the value of MatsSocket#outofbandclose, it also uses
navigator.sendBeacon(..)
(if present, i.e. web browser context) to send an out-of-band Close Session HTTP POST, or, if
'outofbancclose' is a function, this is invoked (if 'outofbandclose' is false
, this
functionality is disabled). Upon receiving the WebSocket close, the server terminates the MatsSocketSession.
The MatsSocket instance's SessionId is made undefined. If there currently is a pipeline,
this will be dropped (i.e. messages deleted), any outstanding receiveCallbacks
(from Requests) are invoked, and received Promises (from sends) are rejected, with type
ReceivedEventType.SESSION_CLOSED, outstanding Reply Promises (from Requests)
are rejected with MessageEventType.SESSION_CLOSED. The effect is to cleanly shut down the
MatsSocketSession (all session data removed from server), and also clean the MatsSocket instance.
Afterwards, the MatsSocket can be started up again by sending a message - keeping its configuration wrt.
terminators, endpoints and listeners. As The SessionId on this client MatsSocket was cleared (and the
previous Session on the server is deleted), this will result in a new server side Session. If you want a
totally clean MatsSocket instance, then just ditch the current instance and make a new one (which then will
have to be configured with terminators etc).
Note: A 'beforeunload' event handler is automatically registered on 'window' (if present, i.e. MatsSocket is
running in a web browser), which invokes this method, so that if the user navigates away, the session will
be closed.
Parameters:
Name | Type | Description |
---|---|---|
reason |
string | short descriptive string. Will be supplied with the webSocket close reason string, and must therefore be quite short (max 123 chars). |
- Source:
deleteSubscription(topicId, messageCallback)
Removes a previously added subscription. If there are no more listeners for this topic,
it is de-subscribed from the server. If the 'messageCallback' was not already registered, an error is
emitted, but the method otherwise returns silently.
Parameters:
Name | Type | Description |
---|---|---|
topicId |
||
messageCallback |
- Source:
endpoint(endpointId, promiseProducer)
Registers an Endpoint, on the specified endpointId, with the specified "promiseProducer". An Endpoint is
the target for Server-to-Client REQUESTs. The promiseProducer is a function that takes a message event
(the incoming REQUEST) and produces a Promise, whose return (resolve or reject) is the return value of the
endpoint.
Note: You cannot register any Terminators, Endpoints or Subscriptions starting with "MatsSocket".
Parameters:
Name | Type | Description |
---|---|---|
endpointId |
the id of this client side Endpoint. | |
promiseProducer |
function | a function that takes a Message Event and returns a Promise which when later either Resolve or Reject will be the return value of the endpoint call. |
- Source:
flush()
Synchronously flush any pipelined messages, i.e. when the method exits, webSocket.send(..) has been invoked
with the serialized pipelined messages, unless the authorization had expired (read more at
MatsSocket#setCurrentAuthorization and MatsSocket#setAuthorizationExpiredCallback).
- Source:
id(length) → {string}
Convenience method for making random strings meant for user reading, e.g. in TraceIds, since this
alphabet only consists of lower and upper case letters, and digits. To make a traceId "unique enough" for
finding it in a log system, a length of 6 should be plenty.
Parameters:
Name | Type | Description |
---|---|---|
length |
number | how long the string should be. 6 should be enough to make a TraceId "unique enough" to uniquely find it in a log system. If you want "absolute certainty" that there never will be any collisions, i.e. a "GUID", go for 20. |
- Source:
Returns:
a random string consisting of characters from from digits, lower and upper case letters
(62 chars).
- Type
- string
jid(length) → {string}
Convenience method for making random strings for correlationIds, not meant for human reading
(choose e.g. length=8), as the alphabet consist of all visible ACSII chars that won't be quoted in a JSON
string. If you want "absolute certainty" that there never will be any collisions, i.e. a "GUID", go for 16.
Parameters:
Name | Type | Description |
---|---|---|
length |
number | how long the string should be, e.g. 8 chars for a very safe correlationId. |
- Source:
Returns:
a random string consisting of characters from all visible and non-JSON-quoted chars of
ASCII (92 chars).
- Type
- string
reconnect(reason, disconnect)
Effectively emulates "lost connection". Used in testing.
If the "disconnect" parameter is true, it will disconnect with MatsSocketCloseCodes.DISCONNECT
instead of MatsSocketCloseCodes.RECONNECT, which will result in the MatsSocket not immediately
starting the reconnection procedure until a new message is added.
Parameters:
Name | Type | Description |
---|---|---|
reason |
String | a string saying why. |
disconnect |
Boolean | whether to close with MatsSocketCloseCodes.DISCONNECT instead of
MatsSocketCloseCodes.RECONNECT - default false . AFAIK, only useful in testing..! |
- Source:
request(endpointId, traceId, message, configOrCallback) → {Promise.<MessageEvent>}
Perform a Request, and have the reply come back via the returned Promise. As opposed to Send, where the
returned Promise is resolved when the server accepts the message, the Promise is now resolved by the Reply.
To get information of whether the server accepted or did not accept the message, you can provide either
a receivedCallback function (set the 'config' parameter to this function) or set the two config properties
'ackCallback' and 'nackCallback' to functions. If you supply the single function variant, this is equivalent
to setting both ack- and nackCallback to the same function. The ReceivedEvent's type will distinguish
between ACK or NACK.
The config object has keys as such - all are optional:
receivedCallback
: {function} invoked when the Server receives the event and either ACK or NACKs it - or when MessageEventType.TIMEOUT or MessageEventType.SESSION_CLOSED happens. This overrides the ack- and nackCallbacks.ackCallback
: {function} invoked when the Server receives the event and ACKs it.nackCallback
: {function} invoked when the Server receives the event and NACKs it - or when MessageEventType.TIMEOUT or MessageEventType.SESSION_CLOSED happens.timeout
: number of milliseconds before the Client times out the Server reply. When this happens, the 'nackCallback' (or receivedCallback if this is used) is invoked with a ReceivedEvent of type ReceivedEventType.TIMEOUT, and the Request's Promise will be rejected with a MessageEvent of type MessageEventType.TIMEOUT.suppressInitiationProcessedEvent
: iftrue
, no event will be sent to listeners added using MatsSocket#addInitiationProcessedEventListener.debug
: If set, this specific call flow overrides the global MatsSocket#debug setting, read more about debug and DebugOptions there.
Parameters:
Name | Type | Description |
---|---|---|
endpointId |
the Server MatsSocket Endpoint that this message should go to. | |
traceId |
the TraceId for this message - will go through all parts of the call, including the Mats flow. | |
message |
the actual message for the Server MatsSocket Endpoint. | |
configOrCallback |
function | object | (optional) either directly a "receivedCallback" function as described in the config object, or a config object - read JSDoc above. |
- Source:
Returns:
- Type
- Promise.<MessageEvent>
requestReplyTo(endpointId, traceId, message, replyToTerminatorId, correlationInformation, config) → {Promise.<ReceivedEvent>}
Perform a Request, but send the reply to a specific client terminator registered on this MatsSocket instance.
The returned Promise functions as for Send, since the reply will not go to the Promise, but to the
terminator. Notice that you can set any CorrelationInformation object which will be available for the Client
terminator when it receives the reply - this is kept on the client (not serialized and sent along with
request and reply), so it can be any object: An identifier, some object to apply the result on, or even a
function.
The config object has keys as such - all are optional:
timeout
: number of milliseconds before the Client times out the Server reply. When this happens, the returned Promise is rejected with a ReceivedEvent of type ReceivedEventType.TIMEOUT, and the specified Client Terminator will have its rejectCallback invoked with a MessageEvent of type MessageEventType.TIMEOUT.suppressInitiationProcessedEvent
: iftrue
, no event will be sent to listeners added using MatsSocket#addInitiationProcessedEventListener.debug
: If set, this specific call flow overrides the global MatsSocket#debug setting, read more about debug and DebugOptions there.
Parameters:
Name | Type | Description |
---|---|---|
endpointId |
the Server MatsSocket Endpoint that this message should go to. | |
traceId |
the TraceId for this message - will go through all parts of the call, including the Mats flow. | |
message |
the actual message for the Server MatsSocket Endpoint. | |
replyToTerminatorId |
which Client Terminator the reply should go to | |
correlationInformation |
information that will be available to the Client Terminator (in MessageEvent#correlationInformation) when the reply comes back. | |
config |
object | an optional configuration object - the one parameter you can set is 'timeout', which works like it does for MatsSocket#request. |
- Source:
Returns:
- Type
- Promise.<ReceivedEvent>
send(endpointId, traceId, message, config) → {Promise.<ReceivedEvent>}
"Fire-and-forget"-style send-a-message. The returned promise is Resolved when the Server receives and accepts
the message for processing, while it is Rejected if the Server denies it.
The config object has a single key - which is optional:
- suppressInitiationProcessedEvent: If
true
, no event will be sent to listeners added using MatsSocket#addInitiationProcessedEventListener.
Parameters:
Name | Type | Description |
---|---|---|
endpointId |
the Server MatsSocket Endpoint/Terminator that this message should go to. | |
traceId |
the TraceId for this message - will go through all parts of the call, including the Mats flow. | |
message |
the actual message for the Server MatsSocket Endpoint. | |
config |
object | an optional configuration object - read JSDoc. |
- Source:
Returns:
- Type
- Promise.<ReceivedEvent>
setAuthorizationExpiredCallback(authorizationExpiredCallback)
If this MatsSockets client realizes that the expiration time (minus the room for latency) of the authorization
has passed when about to send a message, it will invoke this callback function. A new authorization must then
be provided by invoking the 'setCurrentAuthorization' function - only when this is invoked, the MatsSocket
will send messages. The MatsSocket will queue up any messages that are initiated while waiting for new
authorization, and send them all at once in a single pipeline when the new authorization is in.
Parameters:
Name | Type | Description |
---|---|---|
authorizationExpiredCallback |
authorizationExpiredCallback | function which will be invoked
when about to send a new message if
'Date.now() > (expirationTimeMillisSinceEpoch - roomForLatencyMillis) ' from the paramaters of
the last invocation of MatsSocket#setCurrentAuthorization. |
- Source:
setCurrentAuthorization(authorizationValue, expirationTimestamp, roomForLatencyMillis)
Sets an authorization String, which for several types of authorization must be invoked on a regular basis with
fresh authorization - this holds for a OAuth/JWT/OIDC-type system where an access token will expire within a short time
frame (e.g. expires within minutes). For an Oauth2-style authorization scheme, this could be "Bearer: ......".
This must correspond to what the server side authorization plugin expects.
NOTE: This SHALL NOT be used to CHANGE the user! It should only refresh an existing authorization for the
initially authenticated user. One MatsSocket (Session) shall only be used by a single user: If changing
user, you should ditch the existing MatsSocket after invoking MatsSocket#close to properly clean up the
current MatsSocketSession on the server side too, and then make a new MatsSocket thus getting a new Session.
Note: If the underlying WebSocket has not been established and HELLO sent, then invoking this method will NOT
do that - only the first actual MatsSocket message will start the WebSocket and perform the HELLO/WELCOME
handshake.
Parameters:
Name | Type | Description |
---|---|---|
authorizationValue |
string | the string Value which will be transfered to the Server and there resolved to a Principal and UserId on the server side by the AuthorizationPlugin. Note that this value potentially also will be forwarded to other resources that requires authorization. |
expirationTimestamp |
number | the millis-since-epoch at which this authorization expires (in case of OAuth-style tokens), or -1 if it never expires or otherwise has no defined expiration mechanism. Notice that in a JWT token, the expiration time is in seconds, not millis: Multiply by 1000. |
roomForLatencyMillis |
number | the number of millis which is subtracted from the 'expirationTimestamp' to find the point in time where the MatsSocket will refuse to use the authorization and instead invoke the AuthorizationExpiredCallback and wait for a new authorization being set by invocation of the present method. Depending on what the usage of the Authorization string is on server side is, this should probably at least be 10000, i.e. 10 seconds - but if the Mats endpoints uses the Authorization string to do further accesses, both latency and queue time must be taken into account (e.g. for calling into another API that also needs a valid token). If expirationTimestamp is '-1', then this parameter is not used. Default value is 30000 (30 seconds). |
- Source:
subscribe()
Subscribes to a Topic. The Server may do an authorization check for the subscription. If you are not allowed,
a SubscriptionEvent of type SubscriptionEventType.NOT_AUTHORIZED is issued, and the callback
will not get any messages. Otherwise, the event type is SubscriptionEventType.OK.
Note: If the 'messageCallback' was already registered, an error is emitted, but the method otherwise returns
silently.
Note: You will not get messages that was issued before the subscription initially is registered with the
server, which means that you by definition cannot get any messages issued earlier than the initial
ConnectionEventType.SESSION_ESTABLISHED. Code accordingly. Tip for a "ticker stream" or "cache
update stream" or similar: Make sure you have some concept of event sequence number on updates. Do the MatsSocket
connect with the Subscription in place, but for now just queue up any updates. Do the request for "full initial load", whose reply
contains the last applied sequence number. Now process the queued events that arrived while getting the
initial load (i.e. in front, or immediately after), taking into account which event sequence numbers that
already was applied in the initial load: Discard the earlier and same, apply the later. Finally, go over to
immediate processing of the events. If you get a reconnect telling you that messages was lost (next "Note"!),
you could start this process over.
Note: Reconnects are somewhat catered for, in that a "re-subscription" after re-establishing the session will
contain the latest messageId the client has received, and the server will then send along all the messages
after this that was lost - up to some limit specified on the server. If the messageId is not known by the server,
implying that the client has been gone for too long time, a SubscriptionEvent of type
SubscriptionEventType.LOST_MESSAGES is issued. Otherwise, the event type is
SubscriptionEventType.OK.
Note: You should preferably add all "static" subscriptions in the "configuration phase" while setting up
your MatsSocket, before starting it (i.e. sending first message). However, dynamic adding and
deleting is also supported.
Note: Pub/sub is not designed to be as reliable as send/request - but it should be pretty ok anyway!
Wrt. to how many topics a client can subscribe to: Mainly bandwidth constrained wrt. to the total number of
messages, although there is a slight memory and CPU usage to consider too (several hundred should not really
be a problem). In addition, the client needs to send over the actual subscriptions, and if these number in
the thousands, the connect and any reconnects could end up with tens or hundreds of kilobytes of "system
information" passed over the WebSocket.
Wrt. to how many topics that can exist: Mainly memory constrained on the server based on the number of topics
multiplied by the number of subscriptions per topic, in addition to the number of messages passed in total
as each node in the cluster will have to listen to either the full total of messages, or at least a
substantial subset of the messages - and it will also retain these messages for hours to allow for client
reconnects.
Note: You cannot register any Terminators, Endpoints or Subscriptions starting with "MatsSocket".
- Source:
terminator(terminatorId, messageCallback, rejectCallback)
Registers a Terminator, on the specified terminatorId, and with the specified callbacks. A Terminator is
the target for Server-to-Client SENDs, and the Server's REPLYs from invocations of
requestReplyTo(terminatorId ..)
where the terminatorId points to this Terminator.
Note: You cannot register any Terminators, Endpoints or Subscriptions starting with "MatsSocket".
Parameters:
Name | Type | Description |
---|---|---|
terminatorId |
the id of this client side Terminator. | |
messageCallback |
receives an Event when everything went OK, containing the message on the "data" property. | |
rejectCallback |
is relevant if this endpoint is set as the replyTo-target on a requestReplyTo(..) invocation, and will get invoked with the Event if the corresponding Promise-variant would have been rejected. |
- Source:
(inner) _addEnvelopeToPipeline_EvaluatePipelineLater()
Unconditionally adds the supplied envelope to the pipeline, and then evaluates the pipeline,
invokeLater-style so as to get "auth-pipelining". Use flush() to get sync send.
- Source:
(inner) _evaluatePipelineSend()
Sends pipelined messages
- Source: