public interface MatsSocketServer
all message types
and all socket closure modes
).DebugOptions
)AuthenticationPlugin
paired with a Client authentication callback, and a
per-MatsSocketEndpoint, per-message IncomingAuthorizationAndAdapter
.incomingContext.getPrincipal()
and
incomingContext.getUserId()
. The same holds for authorization
of access: If the incoming DTO from the Client demands to see 'top secret folder', you cannot rely on this,
even though you filtered which elements the user can request in a 'folders you are allowed to access'-list in
a previous message to the Client. The user handling the Client could just hack the request DTO to request the top
secret folder even though this was not present in the list of allowed folders. You must therefore again authorize
that the requesting user actually has access to the folder he requests before returning it. This is obviously
exactly the same as for any other transport, e.g. HTTP: It is just to point out that MatsSocket doesn't magically
relieve you from doing proper validation and authorization of incoming message.Modifier and Type | Interface and Description |
---|---|
static interface |
MatsSocketServer.ActiveMatsSocketSession
Represents an active node-local MatsSocketSession - i.e.
|
static class |
MatsSocketServer.ActiveMatsSocketSessionDto
Implementation of
MatsSocketServer.ActiveMatsSocketSession , which is serializable both for MatsSocket and Mats, i.e. |
static class |
MatsSocketServer.DataStoreException
RuntimeException raised from methods which directly interfaces with the
ClusterStoreAndForward and which
cannot "hide" the situation if the data store doesn't work. |
static interface |
MatsSocketServer.IncomingAuthorizationAndAdapter<I,MR,R>
Should handle Authorization evaluation on the supplied
Principal and decide whether this message should be forwarded to the Mats fabric (or directly resolved, rejected
or denied). |
static interface |
MatsSocketServer.LiveMatsSocketSession
A live representation of a MatsSocketSession.
|
static class |
MatsSocketServer.MatsSocketCloseCodes
WebSocket CloseCodes used in MatsSocket, and for what.
|
static interface |
MatsSocketServer.MatsSocketEndpoint<I,MR,R>
Representation of a MatsSocketEndpoint.
|
static interface |
MatsSocketServer.MatsSocketEndpointContext<I,MR,R>
|
static interface |
MatsSocketServer.MatsSocketEndpointIncomingContext<I,MR,R>
The context which the
MatsSocketServer.IncomingAuthorizationAndAdapter gets to work with when handling an incoming
MatsSocket message. |
static interface |
MatsSocketServer.MatsSocketEndpointReplyContext<I,MR,R> |
static class |
MatsSocketServer.MatsSocketEnvelopeDto
This is the entire "Wire transport" DTO of MatsSocket.
|
static class |
MatsSocketServer.MatsSocketEnvelopeWithMetaDto
Extension of
MatsSocketServer.MatsSocketEnvelopeDto which carries some metadata about the processing of the Envelope. |
static interface |
MatsSocketServer.MatsSocketSession
A MatsSocketSession, either as represented in the
data store when gotten via
getMatsSocketSessions(boolean, String, String, String) (returning MatsSocketSessionDto ), or an ActiveMatsSocketSession representing an active
MatsSocketSession connected to this node of the MatsSocketServer instance when gotten via
getActiveMatsSocketSessions() (returning ActiveMatsSocketSessionDto ),
or a LiveMatsSocketSession which is an interface view over the actual live session
in the MatsSocketServer when gotten via getLiveMatsSocketSessions() . |
static class |
MatsSocketServer.MatsSocketSessionDto
Implementation of
MatsSocketServer.MatsSocketSession , which is serializable both for MatsSocket and Mats, i.e. |
static interface |
MatsSocketServer.MessageEvent |
static interface |
MatsSocketServer.MessageEventListener |
static class |
MatsSocketServer.MessageType
All Message Types (aka MatsSocket Envelope Types) used in the wire-protocol of MatsSocket.
|
static interface |
MatsSocketServer.ReplyAdapter<I,MR,R>
Used to transform the reply message from the Mats endpoint to the reply for the MatsSocket endpoint, and decide
whether to resolve or reject the waiting Client-side Promise (i.e.
|
static interface |
MatsSocketServer.SessionEstablishedEvent |
static interface |
MatsSocketServer.SessionEstablishedEventListener |
static interface |
MatsSocketServer.SessionRemovedEvent |
static interface |
MatsSocketServer.SessionRemovedEventListener |
Modifier and Type | Method and Description |
---|---|
void |
addMessageEventListener(MatsSocketServer.MessageEventListener listener)
MessageEventListener s will be invoked for every processed incoming and outgoing
message for any session. |
void |
addSessionEstablishedEventListener(MatsSocketServer.SessionEstablishedEventListener listener)
SessionEstablishedEvent listeners will be invoked when an
LiveMatsSocketSession is established on this node of the
MatsSocketServer instance cluster, i.e. |
void |
addSessionRemovedEventListener(MatsSocketServer.SessionRemovedEventListener listener)
MatsSocketServer.SessionRemovedEvent listeners will be invoked when an MatsSocketServer.LiveMatsSocketSession is removed from this
node of the MatsSocketServer instance cluster - this is both when a MatsSocketSession is
DEREGISTERed , in which case the Client can still
RECONNECT to the same MatsSocketSessionId, and when a
MatsSocketSession is CLOSEd or TIMEOUTed . |
void |
closeSession(java.lang.String sessionId,
java.lang.String reason)
Closes the specified MatsSocketSession - can be used to forcibly close an active MatsSocketSession (i.e.
|
java.util.SortedMap<java.lang.String,MatsSocketServer.ActiveMatsSocketSessionDto> |
getActiveMatsSocketSessions()
This returns static, frozen-in-time, "copied-out" DTO-variants of the
LiveMatsSocketSessions . |
java.util.Map<java.lang.String,MatsSocketServer.LiveMatsSocketSession> |
getLiveMatsSocketSessions()
Imagine that the MatsSocketServer uses a
ConcurrentMap to keep its set of local, live, currently
connected MatsSocketSessions. |
java.util.SortedMap<java.lang.String,MatsSocketServer.MatsSocketEndpoint<?,?,?>> |
getMatsSocketEndpoints() |
java.util.List<MatsSocketServer.MatsSocketSessionDto> |
getMatsSocketSessions(boolean onlyActive,
java.lang.String userId,
java.lang.String appName,
java.lang.String appVersionAtOrAbove)
Unless restricted by the "constraint parameters", this method returns all MatsSocketSessions on this
MatsSocketServer instance, regardless of whether the session currently is connected, and if connected, which node
it is connected to.
|
int |
getMatsSocketSessionsCount(boolean onlyActive,
java.lang.String userId,
java.lang.String appName,
java.lang.String appVersionAtOrAbove)
Like
getMatsSocketSessions(boolean, String, String, String) , only returning the count - this might be
interesting if there are very many sessions, and you do not need the full DTOs of every Session, just the count
for a metric to graph or similar. |
default <I,R> MatsSocketServer.MatsSocketEndpoint<I,?,R> |
matsSocketDirectReplyEndpoint(java.lang.String matsSocketEndpointId,
java.lang.Class<I> incomingClass,
java.lang.Class<R> replyClass,
MatsSocketServer.IncomingAuthorizationAndAdapter<I,java.lang.Void,R> incomingAuthEval)
(Convenience-variant of the base method) Registers a MatsSocket Endpoint meant for situations where you
intend to reply directly in the
MatsSocketServer.IncomingAuthorizationAndAdapter without forwarding to Mats. |
<I,MR,R> MatsSocketServer.MatsSocketEndpoint<I,MR,R> |
matsSocketEndpoint(java.lang.String matsSocketEndpointId,
java.lang.Class<I> incomingClass,
java.lang.Class<MR> matsReplyClass,
java.lang.Class<R> replyClass,
MatsSocketServer.IncomingAuthorizationAndAdapter<I,MR,R> incomingAuthEval,
MatsSocketServer.ReplyAdapter<I,MR,R> replyAdapter)
Registers a MatsSocket Endpoint, including a
MatsSocketServer.ReplyAdapter which can adapt the reply from the Mats
endpoint before being fed back to the MatsSocket - and also decide whether to resolve or reject the waiting
Client Promise. |
default <I,R> MatsSocketServer.MatsSocketEndpoint<I,R,R> |
matsSocketEndpoint(java.lang.String matsSocketEndpointId,
java.lang.Class<I> incomingClass,
java.lang.Class<R> replyClass,
MatsSocketServer.IncomingAuthorizationAndAdapter<I,R,R> incomingAuthEval)
(Convenience-variant of the base method) Registers a MatsSocket Endpoint where there is no replyAdapter -
the reply from the Mats endpoint is directly fed back (as "resolved") to the MatsSocket.
|
default <I> MatsSocketServer.MatsSocketEndpoint<I,java.lang.Void,java.lang.Void> |
matsSocketTerminator(java.lang.String matsSocketEndpointId,
java.lang.Class<I> incomingClass,
MatsSocketServer.IncomingAuthorizationAndAdapter<I,java.lang.Void,java.lang.Void> incomingAuthEval)
(Convenience-variant of the base method) Registers a MatsSocket Terminator (no reply), specifically for
Client-to-Server "SEND", and to accept a "REPLY" from a Server-to-Client "REQUEST".
|
void |
publish(java.lang.String traceId,
java.lang.String topicId,
java.lang.Object messageDto)
Publish a Message to the specified Topic, with the specified TraceId.
|
void |
request(java.lang.String sessionId,
java.lang.String traceId,
java.lang.String clientEndpointId,
java.lang.Object requestDto,
java.lang.String replyToMatsSocketTerminatorId,
java.lang.String correlationString,
byte[] correlationBinary)
Initiates a request to the specified MatsSocketSession, to the specified Client EndpointId, with a replyTo
specified to (typically) a
MatsSocket terminator - which includes a String "correlationString" and byte array "correlationBinary" which can
be used to correlate the reply to the request (available
here and
here for the reply processing). |
void |
send(java.lang.String sessionId,
java.lang.String traceId,
java.lang.String clientTerminatorId,
java.lang.Object messageDto)
Sends a message to the specified MatsSocketSession, to the specified Client TerminatorId.
|
void |
stop(int gracefulShutdownMillis)
Closes all
MatsSocketServer.ActiveMatsSocketSession on this node, closing the WebSocket with
CloseReason.CloseCodes.SERVICE_RESTART (assuming that a MatsSocket service will never truly go down, thus effectively
asking the client to reconnect, hopefully to another instance). |
<I,MR,R> MatsSocketServer.MatsSocketEndpoint<I,MR,R> matsSocketEndpoint(java.lang.String matsSocketEndpointId, java.lang.Class<I> incomingClass, java.lang.Class<MR> matsReplyClass, java.lang.Class<R> replyClass, MatsSocketServer.IncomingAuthorizationAndAdapter<I,MR,R> incomingAuthEval, MatsSocketServer.ReplyAdapter<I,MR,R> replyAdapter)
MatsSocketServer.ReplyAdapter
which can adapt the reply from the Mats
endpoint before being fed back to the MatsSocket - and also decide whether to resolve or reject the waiting
Client Promise.
NOTE: If you supply MatsObject
as the type 'MR', you will get such an instance, and can decide
yourself what to deserialize it to - it will be like having a Java method taking Object as argument. However,
there is no "instanceof" functionality, so you will need to know what type of object it is by other means, e.g.
by putting some up-flow information on the Mats ProcessContext
as a
TraceProperty
.
NOTE: You need not be specific with the 'R' type being created in the MatsSocketServer.ReplyAdapter
- it can be any
superclass of your intended Reply DTO(s), up to Object
. However, the introspection aspects will take a
hit, i.e. when listing all MatsSocketEndpoints
on some monitoring/introspection
page. This is also a bit like with Java: Methods returning Object as return type are annoying, but can
potentially be of value in certain convoluted scenarios.default <I,R> MatsSocketServer.MatsSocketEndpoint<I,R,R> matsSocketEndpoint(java.lang.String matsSocketEndpointId, java.lang.Class<I> incomingClass, java.lang.Class<R> replyClass, MatsSocketServer.IncomingAuthorizationAndAdapter<I,R,R> incomingAuthEval)
MR = R
NOTE: In this case, you cannot specify Object
as the 'R' type - this is due to technical limitations with
how MatsSocket interacts with Mats: You probably have something in mind where a Mats endpoint is configured to
"return Object", i.e. can return whatever type of DTO it wants, and then feed the output of this directly over as
the Reply of the MatsSocket endpoint, and over to the Client. However, Mats's and MatsSocket's serialization
mechanisms are not the same, and can potentially be completely different. Therefore, there needs to be an
intermediary that deserializes whatever comes out of Mats, and (re-)serializes this to the MatsSocket Endpoint's
Reply. This can EITHER be accomplished by specifying a specific class, in which case MatsSocket can handle this
task itself by asking Mats to deserialize to this specified type, and then returning the resulting instance as
the MatsSocket Endpoint Reply (which then will be serialized using the MatsSocket serialization mechanism). With
this solution, there is no need for ReplyAdapter, which is the very intent of the present variant of the
endpoint-creation methods. OTHERWISE, this can be accomplished using user-supplied code, i.e. the ReplyAdapter.
The MatsSocket endpoint can then forward to one, or one of several, Mats endpoints that return a Reply with one
of a finite set of types. The ReplyAdapter would then have to choose which type to deserialize the Mats Reply
into (using the matsObject.toClass(<class>)
functionality), and then
return the desired MatsSocket Reply (which, again, will be serialized using the MatsSocket serialization
mechanism).default <I,R> MatsSocketServer.MatsSocketEndpoint<I,?,R> matsSocketDirectReplyEndpoint(java.lang.String matsSocketEndpointId, java.lang.Class<I> incomingClass, java.lang.Class<R> replyClass, MatsSocketServer.IncomingAuthorizationAndAdapter<I,java.lang.Void,R> incomingAuthEval)
MatsSocketServer.IncomingAuthorizationAndAdapter
without forwarding to Mats.
Types: MR = void
NOTE: In this case, it is possible to specify 'R' = Object
. This is because you do not intend to
interface with Mats at all, so there is no need for MatsSocket Server to know which type any Mats Reply is.default <I> MatsSocketServer.MatsSocketEndpoint<I,java.lang.Void,java.lang.Void> matsSocketTerminator(java.lang.String matsSocketEndpointId, java.lang.Class<I> incomingClass, MatsSocketServer.IncomingAuthorizationAndAdapter<I,java.lang.Void,java.lang.Void> incomingAuthEval)
MR = R = void
request(String, String, String, Object, String, String, byte[])
request}) operations from the Client.void send(java.lang.String sessionId, java.lang.String traceId, java.lang.String clientTerminatorId, java.lang.Object messageDto) throws MatsSocketServer.DataStoreException
MatsSocketServer.DataStoreException
- if the ClusterStoreAndForward
makes any problems when putting the outgoing message in the
outbox.void request(java.lang.String sessionId, java.lang.String traceId, java.lang.String clientEndpointId, java.lang.Object requestDto, java.lang.String replyToMatsSocketTerminatorId, java.lang.String correlationString, byte[] correlationBinary) throws MatsSocketServer.DataStoreException
MatsSocket terminator
- which includes a String "correlationString" and byte array "correlationBinary" which can
be used to correlate the reply to the request (available
here
and
here
for the reply processing). Do note that
since you have no control of when the Client decides to close the browser or terminate the app, you have no
guarantee that a reply will ever come - so code accordingly.
Note: the correlationString
and correlationBinary
are not sent over to the client, but stored
server side in the ClusterStoreAndForward
. This both means that you do not need to be afraid of size (but
storing megabytes is silly anyway), but more importantly, this data cannot be tampered with client side - you can
be safe that what you gave in here is what you get out in the
context.getCorrelationString()
and
context.getCorrelationBinary()
.
Note: To check whether the client Resolved or Rejected the request, use
MatsSocketServer.MatsSocketEndpointIncomingContext.getMessageType()
.
Note: If the specified session is closed when this method is invoked, the message will (effectively) silently be
dropped. Even if you just got hold of the sessionId and it was active then, it might asynchronously close while
you invoke this method.
Note: The message is put in the outbox, and if the session is actually connected, it will be delivered ASAP,
otherwise it will rest in the outbox for delivery once the session reconnects. If the session then closes or
times out while the message is in the outbox, it will be deleted.
Note: Given that the session actually is live and the client is connected or connects before the session is
closed or times out, the guaranteed delivery and exactly-once features are in effect, and this still holds in
face of session reconnects.MatsSocketServer.DataStoreException
- if the ClusterStoreAndForward
makes any problems when putting the outgoing message in the
outbox.void publish(java.lang.String traceId, java.lang.String topicId, java.lang.Object messageDto) throws io.mats3.MatsInitiator.MatsBackendRuntimeException
MatsInitiator.MatsInitiate.publish(Object)
on the MatsFactory
, and thus you might get the
MatsInitiator.MatsBackendRuntimeException
which MatsInitiator.initiateUnchecked(InitiateLambda)
raises.
Note: A published message will be broadcast to all nodes in the MatsSocketServer instance (where each instance
then evaluates if it have subscribers to the topic and forwards to those). In addition, a certain number of
messages per topic will be retained in memory to support "replay of lost messages" when a Client looses
connection and must reconnect. You should consider these facts when designing usage of pub/sub. Messages over
topics should generally be of interest to more than one party. While it is certainly feasible to have
user-specific, or even session-specific topics, which could be authorized to only be subscribable by the "owning
user" or even "owning session" (by use of the
AuthenticationPlugin
), the
current implementation of pub/sub will result in quite a bit of overhead with extensive use of such an approach.
Also, even for messages that are of interest to multiple parties, you should consider the size of the messages:
Maybe not send large PDFs or the entire ISO-images of "newly arrived BlueRays" over a topic - instead send a
small notification about the fresh BlueRay availability including just essential information and an id, and then
the client can decide whether he wants to download it.traceId
- traceId for the flow.topicId
- which Topic to Publish on.messageDto
- the message to Publish.io.mats3.MatsInitiator.MatsBackendRuntimeException
- if the Mats implementation cannot connect to the underlying message broker, or are having problems
interacting with it.java.util.SortedMap<java.lang.String,MatsSocketServer.MatsSocketEndpoint<?,?,?>> getMatsSocketEndpoints()
SortedMap[endpointId, endpoint]
.java.util.List<MatsSocketServer.MatsSocketSessionDto> getMatsSocketSessions(boolean onlyActive, java.lang.String userId, java.lang.String appName, java.lang.String appVersionAtOrAbove) throws MatsSocketServer.DataStoreException
data store
, as opposed to
methods getActiveMatsSocketSessions()
and getLiveMatsSocketSessions()
, which returns result
from this node's internal structures - and therefore only returns sessions that are connected right
now, and are connected to this node. This means that you will get returned both connected sessions,
and sessions that are not currently connected (unless restricting this via parameter 'onlyActive'). The latter
implies that they are state=MatsSocketServer.ActiveMatsSocketSession.MatsSocketSessionState.DEREGISTERED
, and the
MatsSocketServer.MatsSocketSession.getNodeName()
returns Optional.empty()
.
The parameters are constraints - if a parameter is null
or false
, that parameter is not
used in the search criteria, while if it is set, that parameter will constrain the search.onlyActive
- If true
, only returns "active" MatsSocketSessions, currently being connected to some
node, i.e. having MatsSocketServer.MatsSocketSession.getNodeName()
NOT returning Optional.empty()
.userId
- If non-null
, restricts the results to sessions for this particular userIdappName
- If non-null
, restricts the results to sessions for this particular app-name. Do realize
that it is the Client that specifies this value, there is no restriction and you cannot trust that
this String falls within your expected values.appVersionAtOrAbove
- If non-null
, restricts the results to sessions having app-version at or above the
specified value, using ordinary alphanum comparison. Do realize that it is the Client that specifies
this value, there is no restriction and you cannot trust that this String falls within your expected
values.data store
.MatsSocketServer.DataStoreException
- if the ClusterStoreAndForward
makes any problems when reading sessions from it.int getMatsSocketSessionsCount(boolean onlyActive, java.lang.String userId, java.lang.String appName, java.lang.String appVersionAtOrAbove) throws MatsSocketServer.DataStoreException
getMatsSocketSessions(boolean, String, String, String)
, only returning the count - this might be
interesting if there are very many sessions, and you do not need the full DTOs of every Session, just the count
for a metric to graph or similar.data store
.MatsSocketServer.DataStoreException
- if the ClusterStoreAndForward
makes any problems when reading sessions from it.java.util.SortedMap<java.lang.String,MatsSocketServer.ActiveMatsSocketSessionDto> getActiveMatsSocketSessions()
LiveMatsSocketSessions
. Please observe the difference between MatsSocketServer.ActiveMatsSocketSession
and
MatsSocketServer.LiveMatsSocketSession
. If you have a massive amount of sessions, and only need the sessions for
appName="MegaCorpWebBank", then you should consider not employing this method, but instead do a variant of what
this method does, where you restrict the "copy out" to the relevant sessions:
SortedMap<String, ActiveMatsSocketSessionDto> ret = new TreeMap<>(); for (LiveMatsSocketSession liveSession : getLiveMatsSocketSessions().values()) { // === HERE YOU MAY ADD CRITERIA on the LiveMatsSocketSession, doing 'continue' if not matched === // :: "Copy it out" ActiveMatsSocketSessionDto activeSession = liveSession.toActiveMatsSocketSession(); // ?: Check that the LiveSession is still SESSION_ESTABLISHED if (liveSession.getState() != MatsSocketSessionState.SESSION_ESTABLISHED) { // -> No, it changed during copying, so then we drop this. continue; } // Add to result Map ret.put(activeSession.getMatsSocketSessionId(), activeSession); } return ret;
ActiveMatsSocketSession
s - these are the
active MatsSocketSessions which are active right now on this node of the set of
nodes (i.e. cluster) that represents this instance of MatsSocketServer. Notice that all returned
instances had state=SESSION_ESTABLISHED
at the time of
capture.MatsSocketServer.ActiveMatsSocketSession
,
getLiveMatsSocketSessions()
java.util.Map<java.lang.String,MatsSocketServer.LiveMatsSocketSession> getLiveMatsSocketSessions()
ConcurrentMap
to keep its set of local, live, currently
connected MatsSocketSessions. This method then returns an unmodifiable view of this Map. This means that you can
get session instances, and iterate over it, but the contents will change over time as Clients come and go, i.e.
connects and disconnects. It also means that you can get this Map instance once, and keep a local copy of it, and
it will always be current. It again also means that if you want a "static list" of these sessions, either use
getActiveMatsSocketSessions()
which gives you a snapshot, "frozen-in-time" view of the active sessions,
where both the sessions, and the contents of the sessions, are static. Or you may copy the values of this
returned Map into another container - but in the latter case, the contents of those LiveMatsSocketSession
instances are still live. Please observe the difference between MatsSocketServer.ActiveMatsSocketSession
and
MatsSocketServer.LiveMatsSocketSession
.LiveMatsSocketSession
s - these are
the live MatsSocketSessions which are active right now on this node of the set of
nodes (i.e. cluster) that represents this instance of MatsSocketServer.getActiveMatsSocketSessions()
void addSessionEstablishedEventListener(MatsSocketServer.SessionEstablishedEventListener listener)
SessionEstablishedEvent
listeners will be invoked when an
LiveMatsSocketSession
is established on this node of the
MatsSocketServer
instance cluster, i.e. the authentication/authorization is accepted, HELLO message from
Client is processed and MatsSocketSessionId is established. Note that this means that in a fairly load balanced
3-node MatsSocketServer cluster, you should get approximately 1/3 of the SessionEstablishedEvents on "this" node,
while 2/3 of them will come on the "other" two nodes.
Note: A specific MatsSocketSession with a specific MatsSocketSessionId can be established multiple times, due to
RECONNECT
.
NOTE: You are advised against keeping hold of the LiveMatsSocketSession
instance
that is provided in the SessionEstablishedEvent
. You can instead get a view
of the currently live sessions for this node by means of getLiveMatsSocketSessions()
. If you still
decide to hold on to these active sessions instances, you must be very certain to remove it from
your held instances when getting any SessionRemovedEvent
, meaning that you must remove it for any of the DEREGISTER
, CLOSE
and TIMEOUT
event types: The live session instance is dead for all of these events. If you were to remove it only on
CLOSE or TIMEOUT, believing that a DEREGISTER is a "softer" removal, you have basically misunderstood! You could
then get a DEREGISTER (which actually is the server informing you that it has ditched this LiveMatsSocketSession
and the session is now solely represented in the data store
, while you still
stubbornly hold on to it!), and then not get a corresponding TIMEOUT for the same MatsSocketSessionId until many
hours, or days, later. If you fail to remove it at all, you will eventually get an OutOfMemory situation. The
reason here is that a MatsSocketSession instance is never "reanimated", even if the MatsSocketSession is just
DEREGISTERed: A new LiveMatsSocketSession instance is always created upon a SessionEstablishedEvent
, both for NEW
and
RECONNECT
listener
- the SessionEstablishedListener
that shall get invoked when
MatsSocketSessions are established.addSessionRemovedEventListener(SessionRemovedEventListener)
,
getLiveMatsSocketSessions()
,
getActiveMatsSocketSessions()
void addSessionRemovedEventListener(MatsSocketServer.SessionRemovedEventListener listener)
MatsSocketServer.SessionRemovedEvent
listeners will be invoked when an MatsSocketServer.LiveMatsSocketSession
is removed from this
node of the MatsSocketServer
instance cluster - this is both when a MatsSocketSession is
DEREGISTERed
, in which case the Client can still
RECONNECT
to the same MatsSocketSessionId, and when a
MatsSocketSession is CLOSEd
or TIMEOUTed
. In the latter cases, any information of the MatsSocketSession and its MatsSocketSessionId are deleted
from the MatsSocketServer, and the session cannot be reconnected again.
Note: A specific MatsSocketSession can DEREGISTER
multiple times, due
to it can RECONNECT
again after each DEREGISTER. However, once it
has CLOSE
or TIMEOUT
, the session
cannot RECONNECT ever again, and hence those events are terminal wrt. to that specific MatsSocketSessionId.listener
- the SessionEstablishedListener
that shall get invoked when
MatsSocketSessions are removed (either deregistered, closed or timed out).addSessionEstablishedEventListener(SessionEstablishedEventListener)
void addMessageEventListener(MatsSocketServer.MessageEventListener listener)
MessageEventListener
s will be invoked for every processed incoming and outgoing
message for any session. It will be invoked after the message is processed OK on incoming, and
after the message is sent for outgoing. Note that the MatsSocketServer.MatsSocketEnvelopeWithMetaDto
contains more
information than is sent over the wire, this is the "WithMeta" aspect which holds processing metadata - the
wire-part is what is contained in MatsSocketServer.MatsSocketEnvelopeDto
.
Note wrt. modifications on the MatsSocketEnvelopeWithMetaDto
! All fields are public and
non-final, so you can modify it before e.g. sending it over Mats (e.g. nulling out the 'msg' field). However,
read the JavaDoc comment on the class: There is only one single instance for all listeners and
MatsSocketServer.ActiveMatsSocketSession.getLastEnvelopes()
"last envelopes"}, so clone it before modifying!
Note: The last messages per MatsSocketServer.ActiveMatsSocketSession
is available via
MatsSocketServer.ActiveMatsSocketSession.getLastEnvelopes()
.listener
- the MatsSocketServer.MessageEventListener
that will be invoked for every processed incoming and outgoing
envelope for any session.MatsSocketServer.ActiveMatsSocketSession.getLastEnvelopes()
,
MatsSocketServer.MatsSocketEnvelopeWithMetaDto
void closeSession(java.lang.String sessionId, java.lang.String reason)
SessionRemoved
listeners
with type CLOSE
will be issued.
Note: This can be done on any node of the MatsSocketServer-instance cluster, as the instruction will be forwarded
to the active node if the MatsSocketSession is not active on this node. If it is not active on any node, it will
nevertheless be closed in the data store
(i.e. the session cannot reconnect
again).sessionId
- the id of the Session to close.reason
- a short descriptive String of why it was closed.void stop(int gracefulShutdownMillis)
MatsSocketServer.ActiveMatsSocketSession
on this node, closing the WebSocket with
CloseReason.CloseCodes.SERVICE_RESTART
(assuming that a MatsSocket service will never truly go down, thus effectively
asking the client to reconnect, hopefully to another instance). Should be invoked at application shutdown.