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
FieldsModifier and TypeFieldDescriptionstatic final StringA-Z, a-z, 0-9, which is 62 chars.static final StringAll 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 TypeMethodDescriptionvoidMessageEventListeners will be invoked for every processed incoming and outgoing message for any session.voidSessionEstablishedEventlisteners will be invoked when anLiveMatsSocketSessionis established on this node of theMatsSocketServerinstance cluster, i.e.voidMatsSocketServer.SessionRemovedEventlisteners will be invoked when anMatsSocketServer.LiveMatsSocketSessionis removed from this node of theMatsSocketServerinstance cluster - this is both when a MatsSocketSession isDEREGISTERed, in which case the Client can stillRECONNECTto the same MatsSocketSessionId, and when a MatsSocketSession isCLOSEdorTIMEOUTed.voidcloseSession(String matsSocketSessionId, String reason) Closes the specified MatsSocketSession - can be used to forcibly close an active MatsSocketSession (i.e.static MatsSocketServercreateMatsSocketServer(javax.websocket.server.ServerContainer serverContainer, io.mats3.MatsFactory matsFactory, ClusterStoreAndForward clusterStoreAndForward, AuthenticationPlugin authenticationPlugin, String websocketPath) Variant of thefull methodthat uses theappNamethat the MatsFactory is configured with as the 'instanceName' parameter.static MatsSocketServercreateMatsSocketServer(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 aConcurrentMapto 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.intgetMatsSocketSessionsCount(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.ReplyAdapterwhich 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.voidPublish a Message to the specified Topic, with the specified TraceId.voidrequest(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 (availablehereandherefor the reply processing).voidSends a message to the specified MatsSocketSession, to the specified Client TerminatorId.voidstop(int gracefulShutdownMillis) Closes allMatsSocketServer.ActiveMatsSocketSessionon 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, waitMethods inherited from interface io.mats3.matssocket.MatsSocketServer
matsSocketDirectReplyEndpoint, matsSocketEndpoint, matsSocketTerminatorMethods 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 methodthat uses theappNamethat the MatsFactory is configured with as the 'instanceName' parameter.- Parameters:
serverContainer- the WebSocketServerContainer, typically gotten from the Servlet Container.matsFactory- TheMatsFactorywhich we should hook into for both sending requests and setting up endpoints to receive replies.clusterStoreAndForward- an implementation ofClusterStoreAndForwardwhich 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 multipleMatsSocketServers, 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
ServerContainerand 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- TheMatsFactorywhich we should hook into for both sending requests and setting up endpoints to receive replies.clusterStoreAndForward- an implementation ofClusterStoreAndForwardwhich 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 theappNamethat the MatsFactory is configured with.websocketPath- The path onto which the WebSocket Server Endpoint will be mounted. Suggestion: "/matssocket". If you need multipleMatsSocketServers, 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
ServerContainerand 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:MatsSocketServerRegisters a MatsSocket Endpoint, including aMatsSocketServer.ReplyAdapterwhich 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 supplyMatsObjectas 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 MatsProcessContextas 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 MatsSocketEndpointson 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:
matsSocketEndpointin interfaceMatsSocketServer
-
send
public void send(String sessionId, String traceId, String clientTerminatorId, Object messageDto) throws MatsSocketServer.DataStoreException Description copied from interface:MatsSocketServerSends 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:
sendin interfaceMatsSocketServer- Throws:
MatsSocketServer.DataStoreException- if theClusterStoreAndForwardmakes 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:MatsSocketServerInitiates 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 (availablehereandherefor 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: thecorrelationStringandcorrelationBinaryare 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:
requestin interfaceMatsSocketServer- Throws:
MatsSocketServer.DataStoreException- if theClusterStoreAndForwardmakes 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:MatsSocketServerPublish 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.MatsBackendRuntimeExceptionwhichMatsInitiator.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:
publishin 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:
getMatsSocketEndpointsin 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:MatsSocketServerUnless 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 isnullorfalse, that parameter is not used in the search criteria, while if it is set, that parameter will constrain the search.- Specified by:
getMatsSocketSessionsin 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 theClusterStoreAndForwardmakes any problems when reading sessions from it.
-
getMatsSocketSessionsCount
public int getMatsSocketSessionsCount(boolean onlyActive, String userId, String appName, String appVersionAtOrAbove) Description copied from interface:MatsSocketServerLikeMatsSocketServer.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:
getMatsSocketSessionsCountin 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:MatsSocketServerThis returns static, frozen-in-time, "copied-out" DTO-variants of theLiveMatsSocketSessions. Please observe the difference betweenMatsSocketServer.ActiveMatsSocketSessionandMatsSocketServer.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:
getActiveMatsSocketSessionsin interfaceMatsSocketServer- Returns:
- a current snapshot of
ActiveMatsSocketSessions - 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_ESTABLISHEDat the time of capture. - See Also:
-
getLiveMatsSocketSessions
Description copied from interface:MatsSocketServerImagine that the MatsSocketServer uses aConcurrentMapto 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.ActiveMatsSocketSessionandMatsSocketServer.LiveMatsSocketSession.- Specified by:
getLiveMatsSocketSessionsin interfaceMatsSocketServer- Returns:
- an unmodifiable concurrent live view of
LiveMatsSocketSessions - 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:MatsSocketServerCloses 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 listenerswith typeCLOSEwill 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:
closeSessionin 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:MatsSocketServerSessionEstablishedEventlisteners will be invoked when anLiveMatsSocketSessionis established on this node of theMatsSocketServerinstance 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 theLiveMatsSocketSessioninstance 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,CLOSEandTIMEOUTevent 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 forNEWandRECONNECT- Specified by:
addSessionEstablishedEventListenerin interfaceMatsSocketServer- Parameters:
listener- theSessionEstablishedListenerthat shall get invoked when MatsSocketSessions are established.- See Also:
-
addSessionRemovedEventListener
Description copied from interface:MatsSocketServerMatsSocketServer.SessionRemovedEventlisteners will be invoked when anMatsSocketServer.LiveMatsSocketSessionis removed from this node of theMatsSocketServerinstance cluster - this is both when a MatsSocketSession isDEREGISTERed, in which case the Client can stillRECONNECTto the same MatsSocketSessionId, and when a MatsSocketSession isCLOSEdorTIMEOUTed. 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 canDEREGISTERmultiple times, due to it canRECONNECTagain after each DEREGISTER. However, once it hasCLOSEorTIMEOUT, the session cannot RECONNECT ever again, and hence those events are terminal wrt. to that specific MatsSocketSessionId.- Specified by:
addSessionRemovedEventListenerin interfaceMatsSocketServer- Parameters:
listener- theSessionEstablishedListenerthat shall get invoked when MatsSocketSessions are removed (either deregistered, closed or timed out).- See Also:
-
addMessageEventListener
Description copied from interface:MatsSocketServerMessageEventListeners 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.MatsSocketEnvelopeWithMetaDtocontains 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.ActiveMatsSocketSessionis available viaMatsSocketServer.ActiveMatsSocketSession.getLastEnvelopes().- Specified by:
addMessageEventListenerin interfaceMatsSocketServer- Parameters:
listener- theMatsSocketServer.MessageEventListenerthat 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:MatsSocketServerCloses allMatsSocketServer.ActiveMatsSocketSessionon 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:
stopin interfaceMatsSocketServer
-