public class SubProtocolWebSocketHandler extends java.lang.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 |
|---|---|
private class |
SubProtocolWebSocketHandler.Stats |
private static class |
SubProtocolWebSocketHandler.WebSocketSessionHolder |
| Modifier and Type | Field and Description |
|---|---|
private MessageChannel |
clientInboundChannel |
private SubscribableChannel |
clientOutboundChannel |
private SubProtocolHandler |
defaultProtocolHandler |
private long |
lastSessionCheckTime |
private java.lang.Object |
lifecycleMonitor |
private Log |
logger |
private java.util.Map<java.lang.String,SubProtocolHandler> |
protocolHandlerLookup |
private java.util.Set<SubProtocolHandler> |
protocolHandlers |
private boolean |
running |
private int |
sendBufferSizeLimit |
private int |
sendTimeLimit |
private java.util.concurrent.locks.ReentrantLock |
sessionCheckLock |
private java.util.Map<java.lang.String,SubProtocolWebSocketHandler.WebSocketSessionHolder> |
sessions |
private SubProtocolWebSocketHandler.Stats |
stats |
private static int |
TIME_TO_FIRST_MESSAGE
Sessions connected to this handler use a sub-protocol.
|
| Constructor and Description |
|---|
SubProtocolWebSocketHandler(MessageChannel clientInboundChannel,
SubscribableChannel clientOutboundChannel) |
| 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.
|
private void |
checkSessions()
When a session is connected through a higher-level protocol it has a chance
to use heartbeat management to shut down sessions that are too slow to send
or receive messages.
|
private void |
clearSession(WebSocketSession session,
CloseStatus closeStatus) |
protected SubProtocolHandler |
findProtocolHandler(WebSocketSession session) |
SubProtocolHandler |
getDefaultProtocolHandler() |
int |
getPhase()
Return the phase value of this object.
|
java.util.Map<java.lang.String,SubProtocolHandler> |
getProtocolHandlerMap()
Return the sub-protocols keyed by protocol name.
|
java.util.List<SubProtocolHandler> |
getProtocolHandlers() |
int |
getSendBufferSizeLimit() |
int |
getSendTimeLimit() |
java.lang.String |
getStatsInfo()
Return a String describing internal state and counters.
|
java.util.List<java.lang.String> |
getSubProtocols()
Return all supported protocols.
|
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,
java.lang.Throwable exception)
Handle an error from the underlying WebSocket message transport.
|
boolean |
isAutoStartup()
Returns
true if this Lifecycle component should get
started automatically by the container at the time that the containing
ApplicationContext gets refreshed. |
boolean |
isRunning()
Check whether this component is currently running.
|
private java.lang.String |
resolveSessionId(Message<?> message) |
void |
setDefaultProtocolHandler(SubProtocolHandler defaultProtocolHandler)
Set the
SubProtocolHandler to use when the client did not request a
sub-protocol. |
void |
setProtocolHandlers(java.util.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) |
void |
setSendTimeLimit(int sendTimeLimit) |
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(java.lang.Runnable callback)
Indicates that a Lifecycle component must stop if it is currently running.
|
boolean |
supportsPartialMessages()
Whether the WebSocketHandler handles partial messages.
|
java.lang.String |
toString() |
private static final int TIME_TO_FIRST_MESSAGE
checkSessions(),
Constant Field Valuesprivate final Log logger
private final MessageChannel clientInboundChannel
private final SubscribableChannel clientOutboundChannel
private final java.util.Map<java.lang.String,SubProtocolHandler> protocolHandlerLookup
private final java.util.Set<SubProtocolHandler> protocolHandlers
private SubProtocolHandler defaultProtocolHandler
private final java.util.Map<java.lang.String,SubProtocolWebSocketHandler.WebSocketSessionHolder> sessions
private int sendTimeLimit
private int sendBufferSizeLimit
private volatile long lastSessionCheckTime
private final java.util.concurrent.locks.ReentrantLock sessionCheckLock
private final SubProtocolWebSocketHandler.Stats stats
private final java.lang.Object lifecycleMonitor
private volatile boolean running
public SubProtocolWebSocketHandler(MessageChannel clientInboundChannel, SubscribableChannel clientOutboundChannel)
public void setProtocolHandlers(java.util.List<SubProtocolHandler> protocolHandlers)
protocolHandlers - the sub-protocol handlers to usepublic java.util.List<SubProtocolHandler> getProtocolHandlers()
public void addProtocolHandler(SubProtocolHandler handler)
public java.util.Map<java.lang.String,SubProtocolHandler> getProtocolHandlerMap()
public void setDefaultProtocolHandler(SubProtocolHandler defaultProtocolHandler)
SubProtocolHandler to use when the client did not request a
sub-protocol.defaultProtocolHandler - the default handlerpublic SubProtocolHandler getDefaultProtocolHandler()
public java.util.List<java.lang.String> getSubProtocols()
getSubProtocols in interface SubProtocolCapablepublic void setSendTimeLimit(int sendTimeLimit)
public int getSendTimeLimit()
public void setSendBufferSizeLimit(int sendBufferSizeLimit)
public int getSendBufferSizeLimit()
public boolean isAutoStartup()
SmartLifecycletrue if this Lifecycle component should get
started automatically by the container at the time that the containing
ApplicationContext gets refreshed.
A value of false indicates that the component is intended to
be started through an explicit Lifecycle.start() call instead, analogous
to a plain Lifecycle implementation.
isAutoStartup in interface SmartLifecycleLifecycle.start(),
Phased.getPhase(),
LifecycleProcessor.onRefresh(),
ConfigurableApplicationContext.refresh()public int getPhase()
Phasedpublic final boolean isRunning()
LifecycleIn the case of a container, this will return true only if all
components that apply are currently running.
public java.lang.String getStatsInfo()
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, only destroy methods will be called.
Should not throw an exception if the component isn't 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(java.lang.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.
stop in interface SmartLifecycleLifecycle.stop(),
Phased.getPhase()public void afterConnectionEstablished(WebSocketSession session) throws java.lang.Exception
WebSocketHandlerafterConnectionEstablished in interface WebSocketHandlerjava.lang.Exception - this method can handle or propagate exceptions; see class-level
Javadoc for details.protected final SubProtocolHandler findProtocolHandler(WebSocketSession session)
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws java.lang.Exception
handleMessage in interface WebSocketHandlerjava.lang.Exception - 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 handledMessagingExceptionprivate java.lang.String resolveSessionId(Message<?> message)
private void checkSessions()
throws java.io.IOException
java.io.IOExceptionpublic void handleTransportError(WebSocketSession session, java.lang.Throwable exception) throws java.lang.Exception
WebSocketHandlerhandleTransportError in interface WebSocketHandlerjava.lang.Exception - this method can handle or propagate exceptions; see class-level
Javadoc for details.public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws java.lang.Exception
WebSocketHandlerafterConnectionClosed in interface WebSocketHandlerjava.lang.Exception - this method can handle or propagate exceptions; see class-level
Javadoc for details.private void clearSession(WebSocketSession session, CloseStatus closeStatus) throws java.lang.Exception
java.lang.Exceptionpublic 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 WebSocketHandlerpublic java.lang.String toString()
toString in class java.lang.Object