Polish SockJS documentation

master
Rossen Stoyanchev 11 years ago
parent 7af74b2475
commit d30cb17c91
  1. 98
      src/asciidoc/index.adoc

@ -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 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.
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.
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

Loading…
Cancel
Save