Class SubProtocolWebSocketHandler

java.lang.Object
org.springframework.web.socket.messaging.SubProtocolWebSocketHandler
All Implemented Interfaces:
Lifecycle, Phased, SmartLifecycle, MessageHandler, SubProtocolCapable, WebSocketHandler

public class SubProtocolWebSocketHandler extends Object implements WebSocketHandler, SubProtocolCapable, MessageHandler, SmartLifecycle
An implementation of WebSocketHandler that delegates incoming WebSocket messages to a SubProtocolHandler along with a MessageChannel to which the sub-protocol handler can send messages from WebSocket clients to the application.

Also an implementation of MessageHandler that finds the WebSocket session associated with the Message and passes it, along with the message, to the sub-protocol handler to send messages from the application back to the client.

Since:
4.0
Author:
Rossen Stoyanchev, Juergen Hoeller, Andy Wilkinson, Artem Bilan
  • Constructor Details

    • SubProtocolWebSocketHandler

      public SubProtocolWebSocketHandler(MessageChannel clientInboundChannel, SubscribableChannel clientOutboundChannel)
      Create a new SubProtocolWebSocketHandler for the given inbound and outbound channels.
      Parameters:
      clientInboundChannel - the inbound MessageChannel
      clientOutboundChannel - the outbound MessageChannel
  • Method Details

    • setProtocolHandlers

      public void setProtocolHandlers(List<SubProtocolHandler> protocolHandlers)
      Configure one or more handlers to use depending on the sub-protocol requested by the client in the WebSocket handshake request.
      Parameters:
      protocolHandlers - the sub-protocol handlers to use
    • getProtocolHandlers

      public List<SubProtocolHandler> getProtocolHandlers()
    • addProtocolHandler

      public void addProtocolHandler(SubProtocolHandler handler)
      Register a sub-protocol handler.
    • getProtocolHandlerMap

      public Map<String,SubProtocolHandler> getProtocolHandlerMap()
      Return the sub-protocols keyed by protocol name.
    • setDefaultProtocolHandler

      public void setDefaultProtocolHandler(@Nullable SubProtocolHandler defaultProtocolHandler)
      Set the SubProtocolHandler to use when the client did not request a sub-protocol.
      Parameters:
      defaultProtocolHandler - the default handler
    • getDefaultProtocolHandler

      @Nullable public SubProtocolHandler getDefaultProtocolHandler()
      Return the default sub-protocol handler to use.
    • getSubProtocols

      public List<String> getSubProtocols()
      Return all supported protocols.
      Specified by:
      getSubProtocols in interface SubProtocolCapable
    • setSendTimeLimit

      public void setSendTimeLimit(int sendTimeLimit)
      Specify the send-time limit (milliseconds).
      See Also:
    • getSendTimeLimit

      public int getSendTimeLimit()
      Return the send-time limit (milliseconds).
    • setSendBufferSizeLimit

      public void setSendBufferSizeLimit(int sendBufferSizeLimit)
      Specify the buffer-size limit (number of bytes).
      See Also:
    • getSendBufferSizeLimit

      public int getSendBufferSizeLimit()
      Return the buffer-size limit (number of bytes).
    • setTimeToFirstMessage

      public void setTimeToFirstMessage(int timeToFirstMessage)
      Set the maximum time allowed in milliseconds after the WebSocket connection is established and before the first sub-protocol message is received.

      This handler is for WebSocket connections that use a sub-protocol. Therefore, we expect the client to send at least one sub-protocol message in the beginning, or else we assume the connection isn't doing well, e.g. proxy issue, slow network, and can be closed.

      By default this is set to 60,000 (1 minute).

      Parameters:
      timeToFirstMessage - the maximum time allowed in milliseconds
      Since:
      5.1
      See Also:
      • checkSessions()
    • getTimeToFirstMessage

      public int getTimeToFirstMessage()
      Return the maximum time allowed after the WebSocket connection is established and before the first sub-protocol message.
      Since:
      5.1
    • setPhase

      public void setPhase(int phase)
      Set the phase that this handler should run in.

      By default, this is SmartLifecycle.DEFAULT_PHASE.

      Since:
      6.1.4
    • getPhase

      public int getPhase()
      Description copied from interface: SmartLifecycle
      Return the phase that this lifecycle object is supposed to run in.

      The default implementation returns SmartLifecycle.DEFAULT_PHASE in order to let stop() callbacks execute before regular Lifecycle implementations.

      Specified by:
      getPhase in interface Phased
      Specified by:
      getPhase in interface SmartLifecycle
      See Also:
    • getStatsInfo

      public String getStatsInfo()
      Return a String describing internal state and counters. Effectively toString() on getStats().
    • getStats

      Return a structured object with various session counters.
      Since:
      5.2
    • start

      public final void start()
      Description copied from interface: Lifecycle
      Start this component.

      Should not throw an exception if the component is already running.

      In the case of a container, this will propagate the start signal to all components that apply.

      Specified by:
      start in interface Lifecycle
      See Also:
    • stop

      public final void stop()
      Description copied from interface: Lifecycle
      Stop this component, typically in a synchronous fashion, such that the component is fully stopped upon return of this method. Consider implementing SmartLifecycle and its stop(Runnable) variant when asynchronous stop behavior is necessary.

      Note that this stop notification is not guaranteed to come before destruction: On regular shutdown, Lifecycle beans will first receive a stop notification before the general destruction callbacks are being propagated; however, on hot refresh during a context's lifetime or on aborted refresh attempts, a given bean's destroy method will be called without any consideration of stop signals upfront.

      Should not throw an exception if the component is not running (not started yet).

      In the case of a container, this will propagate the stop signal to all components that apply.

      Specified by:
      stop in interface Lifecycle
      See Also:
    • stop

      public final void stop(Runnable callback)
      Description copied from interface: SmartLifecycle
      Indicates that a Lifecycle component must stop if it is currently running.

      The provided callback is used by the LifecycleProcessor to support an ordered, and potentially concurrent, shutdown of all components having a common shutdown order value. The callback must be executed after the SmartLifecycle component does indeed stop.

      The LifecycleProcessor will call only this variant of the stop method; i.e. Lifecycle.stop() will not be called for SmartLifecycle implementations unless explicitly delegated to within the implementation of this method.

      The default implementation delegates to Lifecycle.stop() and immediately triggers the given callback in the calling thread. Note that there is no synchronization between the two, so custom implementations may at least want to put the same steps within their common lifecycle monitor (if any).

      Specified by:
      stop in interface SmartLifecycle
      See Also:
    • isRunning

      public final boolean isRunning()
      Description copied from interface: Lifecycle
      Check whether this component is currently running.

      In the case of a container, this will return true only if all components that apply are currently running.

      Specified by:
      isRunning in interface Lifecycle
      Returns:
      whether the component is currently running
    • afterConnectionEstablished

      public void afterConnectionEstablished(WebSocketSession session) throws Exception
      Description copied from interface: WebSocketHandler
      Invoked after WebSocket negotiation has succeeded and the WebSocket connection is opened and ready for use.
      Specified by:
      afterConnectionEstablished in interface WebSocketHandler
      Throws:
      Exception - this method can handle or propagate exceptions; see class-level Javadoc for details.
    • handleMessage

      public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception
      Handle an inbound message from a WebSocket client.
      Specified by:
      handleMessage in interface WebSocketHandler
      Throws:
      Exception - this method can handle or propagate exceptions; see class-level Javadoc for details.
    • handleMessage

      public void handleMessage(Message<?> message) throws MessagingException
      Handle an outbound Spring Message to a WebSocket client.
      Specified by:
      handleMessage in interface MessageHandler
      Parameters:
      message - the message to be handled
      Throws:
      MessagingException - if the handler failed to process the message
    • handleTransportError

      public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception
      Description copied from interface: WebSocketHandler
      Handle an error from the underlying WebSocket message transport.
      Specified by:
      handleTransportError in interface WebSocketHandler
      Throws:
      Exception - this method can handle or propagate exceptions; see class-level Javadoc for details.
    • afterConnectionClosed

      public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception
      Description copied from interface: WebSocketHandler
      Invoked after the WebSocket connection has been closed by either side, or after a transport error has occurred. Although the session may technically still be open, depending on the underlying implementation, sending messages at this point is discouraged and most likely will not succeed.
      Specified by:
      afterConnectionClosed in interface WebSocketHandler
      Throws:
      Exception - this method can handle or propagate exceptions; see class-level Javadoc for details.
    • supportsPartialMessages

      public boolean supportsPartialMessages()
      Description copied from interface: WebSocketHandler
      Whether the WebSocketHandler handles partial messages. If this flag is set to true and the underlying WebSocket server supports partial messages, then a large WebSocket message, or one of an unknown size may be split and maybe received over multiple calls to WebSocketHandler.handleMessage(WebSocketSession, WebSocketMessage). The flag WebSocketMessage.isLast() indicates if the message is partial and whether it is the last part.
      Specified by:
      supportsPartialMessages in interface WebSocketHandler
    • decorateSession

      protected WebSocketSession decorateSession(WebSocketSession session)
      Decorate the given WebSocketSession, if desired.

      The default implementation builds a ConcurrentWebSocketSessionDecorator with the configured send-time limit and buffer-size limit.

      Parameters:
      session - the original WebSocketSession
      Returns:
      the decorated WebSocketSession, or potentially the given session as-is
      Since:
      4.3.13
    • findProtocolHandler

      protected final SubProtocolHandler findProtocolHandler(WebSocketSession session)
      Find a SubProtocolHandler for the given session.
      Parameters:
      session - the WebSocketSession to find a handler for
    • toString

      public String toString()
      Overrides:
      toString in class Object