Polish SockJS documentation
This commit is contained in:
@@ -37260,73 +37260,63 @@ configuration options, for example, to specify which transports to include.
|
||||
|
||||
|
||||
|
||||
[[websocket-fallback-sockjs-servlet3-async]]
|
||||
==== SockJS and Servlet 3 Async Support
|
||||
|
||||
HTTP streaming and HTTP long polling SockJS transports require a connection to remain
|
||||
open longer than usual. For an overview of these techniques see
|
||||
https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].
|
||||
|
||||
In Servlet containers this is done through Servlet 3 async support that
|
||||
allows exiting the Servlet container thread processing a request and continuing
|
||||
to write to the response from another thread.
|
||||
|
||||
A specific issue is the Servlet API does not provide notifications for a client
|
||||
that has gone away, see https://java.net/jira/browse/SERVLET_SPEC-44[SERVLET_SPEC-44].
|
||||
However, Servlet containers raise an exception on subseqeunt attempts to write
|
||||
to the response. Since Spring's SockJS Service support sever-sent heartbeats (every
|
||||
25 seconds by default), that means a client disconnect is usually detected within that
|
||||
time period or earlier if a message are sent more frequently.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
As a result network IO failures may occur simply because a client has disconnected, which
|
||||
can fill the log with unnecessary stack traces. Spring makes a best effort to identify
|
||||
such network failures that represent client disconnects (specific to each server) and log
|
||||
a more minimal message using the dedicated log category `DISCONNECTED_CLIENT_LOG_CATEGORY`
|
||||
defined in `AbstractSockJsSession`. If you need to see the stack traces, set that
|
||||
log category to TRACE.
|
||||
====
|
||||
|
||||
[[websocket-fallback-sockjs-explained]]
|
||||
==== How SockJS Works
|
||||
An in-depth description of how SockJS works is beyond the scope of this document.
|
||||
This section summarizes a few key facts to aid with understanding.
|
||||
The SockJS protocol itself is defined in a
|
||||
This is a question beyond the scope of this document. The SockJS protocol
|
||||
is defined in the form of a Python
|
||||
https://github.com/sockjs/sockjs-protocol/blob/master/sockjs-protocol-0.3.3.py[test suite],
|
||||
with comments explaining the protocol. There is also an
|
||||
http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[HTML version of that test]
|
||||
showing comments on the right and code on the left.
|
||||
with narrative in comments. There is an
|
||||
http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[HTML formatted version]
|
||||
of the test showing narrative on the right and client code on the left.
|
||||
|
||||
The SockJS client issues HTTP requests with this URL structure:
|
||||
The SockJS client begins with an initial `"/info"` request to obtain basic
|
||||
information from the server. Then the client selects a transport and sends
|
||||
a series of session requests:
|
||||
|
||||
.SockJS URL
|
||||
----
|
||||
http://host:port/{path-to-sockjs-endpoint}/{server-id}/{session-id}/{transport}
|
||||
http://host:port/{sockjs-endpoint}/{server-id}/{session-id}/{transport}
|
||||
----
|
||||
|
||||
The WebSocket transport type uses a single HTTP connection to perform a
|
||||
WebSocket handshake and establish an actual WebSocket session. HTTP-based
|
||||
transports on the other hand must simulate the WebSocket API and at any time
|
||||
may use two HTTP connections -- one for server-to-client messages, via
|
||||
https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates[HTTP streaming or long polling],
|
||||
and another for sending client messages to the server via HTTP POST.
|
||||
The WebSocket transport type only needs a single HTTP connection for the handshake.
|
||||
HTTP-based transports use one connection for sending messages from server to client
|
||||
and separate requests for sending messages from client to server.
|
||||
The session id is used to correlate HTTP requests belonging to the same SockJS
|
||||
session. The server id is not used in the protocol but is added to help in
|
||||
clustered environments.
|
||||
|
||||
The session id is useful with HTTP transports to associate individual HTTP
|
||||
requests that belong to the same SockJS session. The server id is not used in the
|
||||
protocol but is added to help in clustered environments.
|
||||
|
||||
SockJS adds a minimal amount of message framing. For example, the server can send
|
||||
The SockJS protocol requires minimal message framing. The server for examples sends
|
||||
an "open frame" (the letter +o+), a "heartbeat frame" (the letter +h+), or a
|
||||
"close frame" (the letter +c+); while the client sends messages as a JSON-encoded
|
||||
array prepended with the letter `a` (e.g. +a["message1","message2"]+).
|
||||
|
||||
By default the server sends a heartbeat frame every 25 seconds to keep proxies
|
||||
and loadbalancers from timing out the connection.
|
||||
|
||||
|
||||
|
||||
[[websocket-fallback-sockjs-spring]]
|
||||
==== Spring's SockJS Support
|
||||
In the Spring Framework, server-side support for the SockJS protocol is provided through a
|
||||
hierarchy of classes that implement the `SockJsService` interface, while
|
||||
`SockJsHttpRequestHandler` integrates the service into HTTP request processing.
|
||||
|
||||
To implement HTTP streaming and long polling in Servlet containers (both of which require
|
||||
an HTTP connection to remain open longer than usual), Spring's SockJS support
|
||||
relies on Servlet 3 async support.
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
The Servlet API does not provide notifications when a client disconnects,
|
||||
see https://java.net/jira/browse/SERVLET_SPEC-44[SERVLET_SPEC-44]. However,
|
||||
Serlvet containers typically raise an IOException on the next attempt to write
|
||||
to the response at which point the SockJS session is closed. Since the
|
||||
SockJsService sends a heartbeat every 25 seconds, typically a disconnected
|
||||
client should be detected within that time period.
|
||||
|
||||
This also means that network IO failures may occur simply because a client has gone
|
||||
away and that can fill the logs with unnecessary stack traces.
|
||||
We make a best effort to identify such network failures, on a per-server basis, and log
|
||||
them under a separate log category, see `AbstractSockJsSession#DISCONNECTED_CLIENT_LOG_CATEGORY`.
|
||||
A simple one-line message is logged at DEBUG level using this category while a full
|
||||
stack trace is shown at TRACE level.
|
||||
====
|
||||
|
||||
|
||||
|
||||
|
||||
[[websocket-stomp]]
|
||||
=== STOMP Messaging
|
||||
|
||||
Reference in New Issue
Block a user