Package io.mats3.matssocket.impl
Class DefaultMatsSocketServer
java.lang.Object
io.mats3.matssocket.impl.DefaultMatsSocketServer
- All Implemented Interfaces:
MatsSocketStatics
,MatsSocketServer
-
Nested Class Summary
Nested classes/interfaces inherited from interface io.mats3.matssocket.MatsSocketServer
MatsSocketServer.ActiveMatsSocketSession, MatsSocketServer.ActiveMatsSocketSessionDto, MatsSocketServer.DataStoreException, MatsSocketServer.IncomingAuthorizationAndAdapter<I,
MR, R>, MatsSocketServer.LiveMatsSocketSession, MatsSocketServer.MatsSocketCloseCodes, MatsSocketServer.MatsSocketEndpoint<I, MR, R>, MatsSocketServer.MatsSocketEndpointContext<I, MR, R>, MatsSocketServer.MatsSocketEndpointIncomingContext<I, MR, R>, MatsSocketServer.MatsSocketEndpointReplyContext<I, MR, R>, MatsSocketServer.MatsSocketEnvelopeDto, MatsSocketServer.MatsSocketEnvelopeWithMetaDto, MatsSocketServer.MatsSocketSession, MatsSocketServer.MatsSocketSessionDto, MatsSocketServer.MessageEvent, MatsSocketServer.MessageEventListener, MatsSocketServer.MessageType, MatsSocketServer.ReplyAdapter<I, MR, R>, MatsSocketServer.SessionEstablishedEvent, MatsSocketServer.SessionEstablishedEventListener, MatsSocketServer.SessionRemovedEvent, MatsSocketServer.SessionRemovedEventListener Nested classes/interfaces inherited from interface io.mats3.matssocket.impl.MatsSocketStatics
MatsSocketStatics.DebugStackTrace, MatsSocketStatics.DirectJson, MatsSocketStatics.DirectJsonMessageHandlingDeserializer, MatsSocketStatics.MatsSocketEnvelopeDto_Mixin, MatsSocketStatics.MessageToStringDeserializer, MatsSocketStatics.SocketSendIOException
-
Field Summary
Modifier and TypeFieldDescriptionstatic final String
A-Z, a-z, 0-9, which is 62 chars.static final String
All chars from 20-7f, except: Space (32, 0x20) - since spaces are always annoying to use in Ids " (34, 0x22) - since this is the start and end symbol of a String \ (92 0x5c) - since this is the escape char DEL (127, 0x7f) - since this is a control char This is 92 chars.Fields inherited from interface io.mats3.matssocket.impl.MatsSocketStatics
MAX_FORWARDER_POOL_SIZE, MAX_LENGTH_OF_TOPIC_NAME, MAX_NUMBER_OF_COMPENSATING_TRANSACTIONS_ATTEMPTS, MAX_NUMBER_OF_HELD_ENVELOPES_PER_SESSION, MAX_NUMBER_OF_MESSAGES_PER_FORWARD_LOOP, MAX_NUMBER_OF_OUTBOX_STORE_ATTEMPTS_CSAF, MAX_NUMBER_OF_RECORDED_ENVELOPES_PER_SESSION, MAX_NUMBER_OF_REDELIVERY_ATTEMPTS, MAX_NUMBER_OF_SESSIONS_PER_USER_ID, MAX_NUMBER_OF_TOPICS_PER_SESSION, MAX_SIZE_OF_HELD_ENVELOPE_MSGS, MDC_CLIENT_APP_NAME_AND_VERSION, MDC_CLIENT_LIB_AND_VERSIONS, MDC_CMID, MDC_MESSAGE_TYPE, MDC_PRINCIPAL_NAME, MDC_SESSION_ID, MDC_SMID, MDC_TRACE_ID, MDC_USER_ID, MILLIS_BETWEEN_COMPENSATING_TRANSACTIONS_ATTEMPTS, MILLIS_BETWEEN_LIVELINESS_UPDATE_RUN, MILLIS_BETWEEN_SCAVENGE_SESSION_REMNANTS_RUN, MILLIS_BETWEEN_SESSION_TIMEOUT_RUN, MILLIS_SESSION_TIMEOUT_SUPPLIER, MIN_FORWARDER_POOL_SIZE, NUMBER_OF_OUTGOING_ENVELOPES_SCHEDULER_THREADS, THREAD_PREFIX
-
Method Summary
Modifier and TypeMethodDescriptionvoid
MessageEventListener
s will be invoked for every processed incoming and outgoing message for any session.void
SessionEstablishedEvent
listeners will be invoked when anLiveMatsSocketSession
is established on this node of theMatsSocketServer
instance cluster, i.e.void
MatsSocketServer.SessionRemovedEvent
listeners will be invoked when anMatsSocketServer.LiveMatsSocketSession
is removed from this node of theMatsSocketServer
instance cluster - this is both when a MatsSocketSession isDEREGISTERed
, in which case the Client can stillRECONNECT
to the same MatsSocketSessionId, and when a MatsSocketSession isCLOSEd
orTIMEOUTed
.void
closeSession
(String matsSocketSessionId, String reason) Closes the specified MatsSocketSession - can be used to forcibly close an active MatsSocketSession (i.e.static MatsSocketServer
createMatsSocketServer
(javax.websocket.server.ServerContainer serverContainer, io.mats3.MatsFactory matsFactory, ClusterStoreAndForward clusterStoreAndForward, AuthenticationPlugin authenticationPlugin, String websocketPath) Variant of thefull method
that uses theappName
that the MatsFactory is configured with as the 'instanceName' parameter.static MatsSocketServer
createMatsSocketServer
(javax.websocket.server.ServerContainer serverContainer, io.mats3.MatsFactory matsFactory, ClusterStoreAndForward clusterStoreAndForward, AuthenticationPlugin authenticationPlugin, String instanceName, String websocketPath) Create a MatsSocketServer, piecing together necessary bits.This returns static, frozen-in-time, "copied-out" DTO-variants of theLiveMatsSocketSessions
.Imagine that the MatsSocketServer uses aConcurrentMap
to keep its set of local, live, currently connected MatsSocketSessions.getMatsSocketSessions
(boolean onlyActive, String userId, String appName, 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, String userId, String appName, String appVersionAtOrAbove) LikeMatsSocketServer.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.<I,
MR, R> MatsSocketServer.MatsSocketEndpoint<I, MR, R> matsSocketEndpoint
(String matsSocketEndpointId, Class<I> incomingClass, Class<MR> matsReplyClass, Class<R> msReplyClass, MatsSocketServer.IncomingAuthorizationAndAdapter<I, MR, R> incomingAuthEval, MatsSocketServer.ReplyAdapter<I, MR, R> replyAdapter) Registers a MatsSocket Endpoint, including aMatsSocketServer.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.void
Publish a Message to the specified Topic, with the specified TraceId.void
request
(String sessionId, String traceId, String clientEndpointId, Object requestDto, String replyToMatsSocketTerminatorId, String correlationString, byte[] correlationBinary) Initiates a request to the specified MatsSocketSession, to the specified Client EndpointId, with a replyTo specified to (typically) aMatsSocket terminator
- which includes a String "correlationString" and byte array "correlationBinary" which can be used to correlate the reply to the request (availablehere
andhere
for the reply processing).void
Sends a message to the specified MatsSocketSession, to the specified Client TerminatorId.void
stop
(int gracefulShutdownMillis) Closes allMatsSocketServer.ActiveMatsSocketSession
on this node, closing the WebSocket withCloseReason.CloseCodes.SERVICE_RESTART
(assuming that a MatsSocket service will never truly go down, thus effectively asking the client to reconnect, hopefully to another instance).Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface io.mats3.matssocket.MatsSocketServer
matsSocketDirectReplyEndpoint, matsSocketEndpoint, matsSocketTerminator
Methods inherited from interface io.mats3.matssocket.impl.MatsSocketStatics
jacksonMapper, ms, msSince
-
Field Details
-
ALPHABET
A-Z, a-z, 0-9, which is 62 chars.- See Also:
-
ALPHABET_JSON_ID
All chars from 20-7f, except:- Space (32, 0x20) - since spaces are always annoying to use in Ids
- " (34, 0x22) - since this is the start and end symbol of a String
- \ (92 0x5c) - since this is the escape char
- DEL (127, 0x7f) - since this is a control char
-
-
Method Details
-
createMatsSocketServer
public static MatsSocketServer createMatsSocketServer(javax.websocket.server.ServerContainer serverContainer, io.mats3.MatsFactory matsFactory, ClusterStoreAndForward clusterStoreAndForward, AuthenticationPlugin authenticationPlugin, String websocketPath) Variant of thefull method
that uses theappName
that the MatsFactory is configured with as the 'instanceName' parameter.- Parameters:
serverContainer
- the WebSocketServerContainer
, typically gotten from the Servlet Container.matsFactory
- TheMatsFactory
which we should hook into for both sending requests and setting up endpoints to receive replies.clusterStoreAndForward
- an implementation ofClusterStoreAndForward
which temporarily holds replies while finding the right node that holds the WebSocket connection - and hold them till the client reconnects in case he has disconnected in the mean time.authenticationPlugin
- the piece of code that turns an Authorization String into a Principal. Must be pretty fast, as it is invoked synchronously - keep any IPC fast, otherwise all your threads of the container might be used up. If the function throws or returns null, authorization did not go through.websocketPath
- The path onto which the WebSocket Server Endpoint will be mounted. Suggestion: "/matssocket". If you need multipleMatsSocketServer
s, e.g. because you need two types of authentication, they need to be mounted on different paths.- Returns:
- a MatsSocketServer instance, now hooked into both the WebSocket
ServerContainer
and theMatsFactory
.
-
createMatsSocketServer
public static MatsSocketServer createMatsSocketServer(javax.websocket.server.ServerContainer serverContainer, io.mats3.MatsFactory matsFactory, ClusterStoreAndForward clusterStoreAndForward, AuthenticationPlugin authenticationPlugin, String instanceName, String websocketPath) Create a MatsSocketServer, piecing together necessary bits.- Parameters:
serverContainer
- the WebSocketServerContainer
, typically gotten from the Servlet Container.matsFactory
- TheMatsFactory
which we should hook into for both sending requests and setting up endpoints to receive replies.clusterStoreAndForward
- an implementation ofClusterStoreAndForward
which temporarily holds replies while finding the right node that holds the WebSocket connection - and hold them till the client reconnects in case he has disconnected in the mean time.authenticationPlugin
- the piece of code that turns an Authorization String into a Principal. Must be pretty fast, as it is invoked synchronously - keep any IPC fast, otherwise all your threads of the container might be used up. If the function throws or returns null, authorization did not go through.instanceName
- a unique name of this MatsSocketServer setup, at least within the MQ system the MatsFactory is connected to, as it is used to postfix/uniquify the endpoints that the MatsSocketServer creates on the MatsFactory. To illustrate: The variant of this factory method that does not take 'instanceName' uses theappName
that the MatsFactory is configured with.websocketPath
- The path onto which the WebSocket Server Endpoint will be mounted. Suggestion: "/matssocket". If you need multipleMatsSocketServer
s, e.g. because you need two types of authentication, they need to be mounted on different paths.- Returns:
- a MatsSocketServer instance, now hooked into both the WebSocket
ServerContainer
and theMatsFactory
.
-
getWebSocketOutgoingEnvelopes
-
getIncomingSrrMsgHandler
-
matsSocketEndpoint
public <I,MR, MatsSocketServer.MatsSocketEndpoint<I,R> MR, matsSocketEndpointR> (String matsSocketEndpointId, Class<I> incomingClass, Class<MR> matsReplyClass, Class<R> msReplyClass, MatsSocketServer.IncomingAuthorizationAndAdapter<I, MR, R> incomingAuthEval, MatsSocketServer.ReplyAdapter<I, MR, R> replyAdapter) Description copied from interface:MatsSocketServer
Registers a MatsSocket Endpoint, including aMatsSocketServer.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 supplyMatsObject
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 MatsProcessContext
as aTraceProperty
. NOTE: You need not be specific with the 'R' type being created in theMatsSocketServer.ReplyAdapter
- it can be any superclass of your intended Reply DTO(s), up toObject
. However, the introspection aspects will take a hit, i.e. when listingall 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.- Specified by:
matsSocketEndpoint
in interfaceMatsSocketServer
-
send
public void send(String sessionId, String traceId, String clientTerminatorId, Object messageDto) throws MatsSocketServer.DataStoreException Description copied from interface:MatsSocketServer
Sends a message to the specified MatsSocketSession, to the specified Client TerminatorId. This is "fire into the void" style messaging, where you have no idea of whether the client received the message. Usage scenarios include "New information about order progress" which may or may not include said information (if not included, the client must do a request to update) - but where the server does not really care if the client gets the information, only that if he actually has the webpage/app open at the time, he will get the message and thus update his view of the changed world. 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.- Specified by:
send
in interfaceMatsSocketServer
- Throws:
MatsSocketServer.DataStoreException
- if theClusterStoreAndForward
makes any problems when putting the outgoing message in the outbox.
-
request
public void request(String sessionId, String traceId, String clientEndpointId, Object requestDto, String replyToMatsSocketTerminatorId, String correlationString, byte[] correlationBinary) throws MatsSocketServer.DataStoreException Description copied from interface:MatsSocketServer
Initiates a request to the specified MatsSocketSession, to the specified Client EndpointId, with a replyTo specified to (typically) aMatsSocket terminator
- which includes a String "correlationString" and byte array "correlationBinary" which can be used to correlate the reply to the request (availablehere
andhere
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: thecorrelationString
andcorrelationBinary
are not sent over to the client, but stored server side in theClusterStoreAndForward
. 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 thecontext.getCorrelationString()
andcontext.getCorrelationBinary()
. Note: To check whether the client Resolved or Rejected the request, useMatsSocketServer.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.- Specified by:
request
in interfaceMatsSocketServer
- Throws:
MatsSocketServer.DataStoreException
- if theClusterStoreAndForward
makes any problems when putting the outgoing message in the outbox.
-
publish
public void publish(String traceId, String topicId, Object messageDto) throws io.mats3.MatsInitiator.MatsBackendRuntimeException Description copied from interface:MatsSocketServer
Publish a Message to the specified Topic, with the specified TraceId. This is pretty much a direct invocation ofMatsInitiator.MatsInitiate.publish(Object)
on theMatsFactory
, and thus you might get theMatsInitiator.MatsBackendRuntimeException
whichMatsInitiator.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 theAuthenticationPlugin
), 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.- Specified by:
publish
in interfaceMatsSocketServer
- Parameters:
traceId
- traceId for the flow.topicId
- which Topic to Publish on.messageDto
- the message to Publish.- Throws:
io.mats3.MatsInitiator.MatsBackendRuntimeException
- if the Mats implementation cannot connect to the underlying message broker, or are having problems interacting with it.
-
getMatsSocketEndpoints
- Specified by:
getMatsSocketEndpoints
in interfaceMatsSocketServer
- Returns:
- all registered MatsSocketEndpoints, as a
SortedMap[endpointId, endpoint]
.
-
getMatsSocketSessions
public List<MatsSocketServer.MatsSocketSessionDto> getMatsSocketSessions(boolean onlyActive, String userId, String appName, String appVersionAtOrAbove) throws MatsSocketServer.DataStoreException Description copied from interface:MatsSocketServer
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. This is done by reading from thedata store
, as opposed to methodsMatsSocketServer.getActiveMatsSocketSessions()
andMatsSocketServer.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 theMatsSocketServer.MatsSocketSession.getNodeName()
returnsOptional.empty()
. The parameters are constraints - if a parameter isnull
orfalse
, that parameter is not used in the search criteria, while if it is set, that parameter will constrain the search.- Specified by:
getMatsSocketSessions
in interfaceMatsSocketServer
- Parameters:
onlyActive
- Iftrue
, only returns "active" MatsSocketSessions, currently being connected to some node, i.e. havingMatsSocketServer.MatsSocketSession.getNodeName()
NOT returningOptional.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.- Returns:
- the list of all MatsSocketSessions currently registered with this MatsSocketServer instance matching the
constraints if set - as read from the
data store
. - Throws:
MatsSocketServer.DataStoreException
- if theClusterStoreAndForward
makes any problems when reading sessions from it.
-
getMatsSocketSessionsCount
public int getMatsSocketSessionsCount(boolean onlyActive, String userId, String appName, String appVersionAtOrAbove) Description copied from interface:MatsSocketServer
LikeMatsSocketServer.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.- Specified by:
getMatsSocketSessionsCount
in interfaceMatsSocketServer
- Returns:
- the count of all MatsSocketSessions currently registered with this MatsSocketServer instance matching the
constraints if set - as read from the
data store
.
-
getActiveMatsSocketSessions
Description copied from interface:MatsSocketServer
This returns static, frozen-in-time, "copied-out" DTO-variants of theLiveMatsSocketSessions
. Please observe the difference betweenMatsSocketServer.ActiveMatsSocketSession
andMatsSocketServer.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;
- Specified by:
getActiveMatsSocketSessions
in interfaceMatsSocketServer
- Returns:
- a current snapshot of
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. - See Also:
-
getLiveMatsSocketSessions
Description copied from interface:MatsSocketServer
Imagine that the MatsSocketServer uses aConcurrentMap
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 useMatsSocketServer.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 betweenMatsSocketServer.ActiveMatsSocketSession
andMatsSocketServer.LiveMatsSocketSession
.- Specified by:
getLiveMatsSocketSessions
in interfaceMatsSocketServer
- Returns:
- an unmodifiable concurrent live view of
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. - See Also:
-
closeSession
Description copied from interface:MatsSocketServer
Closes the specified MatsSocketSession - can be used to forcibly close an active MatsSocketSession (i.e. "kick it off"), and can also used to perform out-of-band closing of Session if the WebSocket is down (this is used in the MatsSocket.js Client, where an "onunload"-listener is attached, so that if the user navigates away, every effort is done to get the MatsSocketSession closed). Note: An invocation of anySessionRemoved listeners
with typeCLOSE
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 thedata store
(i.e. the session cannot reconnect again).- Specified by:
closeSession
in interfaceMatsSocketServer
- Parameters:
matsSocketSessionId
- the id of the Session to close.reason
- a short descriptive String of why it was closed.
-
addSessionEstablishedEventListener
public void addSessionEstablishedEventListener(MatsSocketServer.SessionEstablishedEventListener listener) Description copied from interface:MatsSocketServer
SessionEstablishedEvent
listeners will be invoked when anLiveMatsSocketSession
is established on this node of theMatsSocketServer
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 toRECONNECT
. NOTE: You are advised against keeping hold of theLiveMatsSocketSession
instance that is provided in theSessionEstablishedEvent
. You can instead get a view of the currently live sessions for this node by means ofMatsSocketServer.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 anySessionRemovedEvent
, meaning that you must remove it for any of theDEREGISTER
,CLOSE
andTIMEOUT
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 thedata 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 aSessionEstablishedEvent
, both forNEW
andRECONNECT
- Specified by:
addSessionEstablishedEventListener
in interfaceMatsSocketServer
- Parameters:
listener
- theSessionEstablishedListener
that shall get invoked when MatsSocketSessions are established.- See Also:
-
addSessionRemovedEventListener
Description copied from interface:MatsSocketServer
MatsSocketServer.SessionRemovedEvent
listeners will be invoked when anMatsSocketServer.LiveMatsSocketSession
is removed from this node of theMatsSocketServer
instance cluster - this is both when a MatsSocketSession isDEREGISTERed
, in which case the Client can stillRECONNECT
to the same MatsSocketSessionId, and when a MatsSocketSession isCLOSEd
orTIMEOUTed
. 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 canDEREGISTER
multiple times, due to it canRECONNECT
again after each DEREGISTER. However, once it hasCLOSE
orTIMEOUT
, the session cannot RECONNECT ever again, and hence those events are terminal wrt. to that specific MatsSocketSessionId.- Specified by:
addSessionRemovedEventListener
in interfaceMatsSocketServer
- Parameters:
listener
- theSessionEstablishedListener
that shall get invoked when MatsSocketSessions are removed (either deregistered, closed or timed out).- See Also:
-
addMessageEventListener
Description copied from interface:MatsSocketServer
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 theMatsSocketServer.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 inMatsSocketServer.MatsSocketEnvelopeDto
. Note wrt. modifications on theMatsSocketEnvelopeWithMetaDto
! 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 andMatsSocketServer.ActiveMatsSocketSession.getLastEnvelopes()
"last envelopes"}, so clone it before modifying! Note: The last messages perMatsSocketServer.ActiveMatsSocketSession
is available viaMatsSocketServer.ActiveMatsSocketSession.getLastEnvelopes()
.- Specified by:
addMessageEventListener
in interfaceMatsSocketServer
- Parameters:
listener
- theMatsSocketServer.MessageEventListener
that will be invoked for every processed incoming and outgoing envelope for any session.- See Also:
-
stop
public void stop(int gracefulShutdownMillis) Description copied from interface:MatsSocketServer
Closes allMatsSocketServer.ActiveMatsSocketSession
on this node, closing the WebSocket withCloseReason.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.- Specified by:
stop
in interfaceMatsSocketServer
-