org.springframework.web.socket.messaging

## 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

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static interface` | `SubProtocolWebSocketHandler.Stats` Contract for access to session counters.

  - ### Field Summary

    - ### Fields inherited from interface org.springframework.context.SmartLifecycle

      `DEFAULT_PHASE`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `SubProtocolWebSocketHandler(MessageChannel clientInboundChannel, SubscribableChannel clientOutboundChannel)` Create a new `SubProtocolWebSocketHandler` for the given inbound and outbound channels.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `addProtocolHandler(SubProtocolHandler handler)` Register a sub-protocol handler.
    `void` | `afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus)` Invoked after the WebSocket connection has been closed by either side, or after a transport error has occurred.
    `void` | `afterConnectionEstablished(WebSocketSession session)` Invoked after WebSocket negotiation has succeeded and the WebSocket connection is opened and ready for use.
    `protected WebSocketSession` | `decorateSession(WebSocketSession session)` Decorate the given `WebSocketSession`, if desired.
    `protected SubProtocolHandler` | `findProtocolHandler(WebSocketSession session)` Find a `SubProtocolHandler` for the given session.
    `SubProtocolHandler` | `getDefaultProtocolHandler()` Return the default sub-protocol handler to use.
    `Map<String,SubProtocolHandler>` | `getProtocolHandlerMap()` Return the sub-protocols keyed by protocol name.
    `List<SubProtocolHandler>` | `getProtocolHandlers()`
    `int` | `getSendBufferSizeLimit()` Return the buffer-size limit (number of bytes).
    `int` | `getSendTimeLimit()` Return the send-time limit (milliseconds).
    `SubProtocolWebSocketHandler.Stats` | `getStats()` Return a structured object with various session counters.
    `String` | `getStatsInfo()` Return a String describing internal state and counters.
    `List<String>` | `getSubProtocols()` Return all supported protocols.
    `int` | `getTimeToFirstMessage()` Return the maximum time allowed after the WebSocket connection is established and before the first sub-protocol message.
    `void` | `handleMessage(Message<?> message)` Handle an outbound Spring Message to a WebSocket client.
    `void` | `handleMessage(WebSocketSession session, WebSocketMessage<?> message)` Handle an inbound message from a WebSocket client.
    `void` | `handleTransportError(WebSocketSession session, Throwable exception)` Handle an error from the underlying WebSocket message transport.
    `boolean` | `isRunning()` Check whether this component is currently running.
    `void` | `setDefaultProtocolHandler(SubProtocolHandler defaultProtocolHandler)` Set the `SubProtocolHandler` to use when the client did not request a sub-protocol.
    `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.
    `void` | `setSendBufferSizeLimit(int sendBufferSizeLimit)` Specify the buffer-size limit (number of bytes).
    `void` | `setSendTimeLimit(int sendTimeLimit)` Specify the send-time limit (milliseconds).
    `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.
    `void` | `start()` Start this component.
    `void` | `stop()` Stop this component, typically in a synchronous fashion, such that the component is fully stopped upon return of this method.
    `void` | `stop(Runnable callback)` Indicates that a Lifecycle component must stop if it is currently running.
    `boolean` | `supportsPartialMessages()` Whether the WebSocketHandler handles partial messages.
    `String` | `toString()`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

    - ### Methods inherited from interface org.springframework.context.SmartLifecycle

      `getPhase, isAutoStartup`

- - ### Constructor Detail

    - #### 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 Detail

    - #### 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:
        `ConcurrentWebSocketSessionDecorator`

    - #### 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:
        `ConcurrentWebSocketSessionDecorator`

    - #### 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

    - #### getStatsInfo

          public String getStatsInfo()

      Return a String describing internal state and counters. Effectively `toString()` on `getStats()`.

    - #### getStats

          public SubProtocolWebSocketHandler.Stats 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:
        `SmartLifecycle.isAutoStartup()`

    - #### 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:
        `SmartLifecycle.stop(Runnable)`, `DisposableBean.destroy()`

    - #### 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:
        `Lifecycle.stop()`, `SmartLifecycle.getPhase()`

    - #### 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`