public class SubProtocolWebSocketHandler extends Object implements WebSocketHandler, SubProtocolCapable, MessageHandler, SmartLifecycle
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.
| Modifier and Type | Class and Description |
|---|---|
static interface |
SubProtocolWebSocketHandler.Stats
Contract for access to session counters.
|
DEFAULT_PHASE| Constructor and Description |
|---|
SubProtocolWebSocketHandler(MessageChannel clientInboundChannel,
SubscribableChannel clientOutboundChannel)
Create a new
SubProtocolWebSocketHandler for the given inbound and outbound channels. |
| 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() |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitgetPhase, isAutoStartuppublic SubProtocolWebSocketHandler(MessageChannel clientInboundChannel, SubscribableChannel clientOutboundChannel)
SubProtocolWebSocketHandler for the given inbound and outbound channels.clientInboundChannel - the inbound MessageChannelclientOutboundChannel - the outbound MessageChannelpublic void setProtocolHandlers(List<SubProtocolHandler> protocolHandlers)
protocolHandlers - the sub-protocol handlers to usepublic List<SubProtocolHandler> getProtocolHandlers()
public void addProtocolHandler(SubProtocolHandler handler)
public Map<String,SubProtocolHandler> getProtocolHandlerMap()
public void setDefaultProtocolHandler(@Nullable SubProtocolHandler defaultProtocolHandler)
SubProtocolHandler to use when the client did not request a
sub-protocol.defaultProtocolHandler - the default handler@Nullable public SubProtocolHandler getDefaultProtocolHandler()
public List<String> getSubProtocols()
getSubProtocols in interface SubProtocolCapablepublic void setSendTimeLimit(int sendTimeLimit)
ConcurrentWebSocketSessionDecoratorpublic int getSendTimeLimit()
public void setSendBufferSizeLimit(int sendBufferSizeLimit)
ConcurrentWebSocketSessionDecoratorpublic int getSendBufferSizeLimit()
public void setTimeToFirstMessage(int timeToFirstMessage)
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).
timeToFirstMessage - the maximum time allowed in millisecondscheckSessions()public int getTimeToFirstMessage()
public String getStatsInfo()
toString() on getStats().public SubProtocolWebSocketHandler.Stats getStats()
public final void start()
LifecycleShould 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.
start in interface LifecycleSmartLifecycle.isAutoStartup()public final void stop()
LifecycleSmartLifecycle
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.
stop in interface LifecycleSmartLifecycle.stop(Runnable),
DisposableBean.destroy()public final void stop(Runnable callback)
SmartLifecycleThe 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).
stop in interface SmartLifecycleLifecycle.stop(),
SmartLifecycle.getPhase()public final boolean isRunning()
LifecycleIn the case of a container, this will return true only if all
components that apply are currently running.
public void afterConnectionEstablished(WebSocketSession session) throws Exception
WebSocketHandlerafterConnectionEstablished in interface WebSocketHandlerException - this method can handle or propagate exceptions; see class-level
Javadoc for details.public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception
handleMessage in interface WebSocketHandlerException - this method can handle or propagate exceptions; see class-level
Javadoc for details.public void handleMessage(Message<?> message) throws MessagingException
handleMessage in interface MessageHandlermessage - the message to be handledMessagingException - if the handler failed to process the messagepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception
WebSocketHandlerhandleTransportError in interface WebSocketHandlerException - this method can handle or propagate exceptions; see class-level
Javadoc for details.public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception
WebSocketHandlerafterConnectionClosed in interface WebSocketHandlerException - this method can handle or propagate exceptions; see class-level
Javadoc for details.public boolean supportsPartialMessages()
WebSocketHandlertrue 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.supportsPartialMessages in interface WebSocketHandlerprotected WebSocketSession decorateSession(WebSocketSession session)
WebSocketSession, if desired.
The default implementation builds a ConcurrentWebSocketSessionDecorator
with the configured send-time limit and
buffer-size limit.
session - the original WebSocketSessionWebSocketSession, or potentially the given session as-isprotected final SubProtocolHandler findProtocolHandler(WebSocketSession session)
SubProtocolHandler for the given session.session - the WebSocketSession to find a handler for