Vaadin Push Invalid JSON from Server 1 X
If Vaadin is failing with “Invalid JSON from server: 1|X”, read on.
The problem is that Vaadin expects an UIDL JSON message over the websocket pipe and can’t parse 1|X
. Where did 1|X
came from?
Atmosphere sends data in the format of length|message
, which means that
1|X
is an Atmosphere message “X” of length 1. It’s a
HeartbeatInterceptor
message which should be part of the internal Atmosphere heartbeat mechanism and should
be filtered out by Atmosphere and thus ignored by Vaadin.
This kind of message is sent every 60 seconds by default by Atmosphere in all Vaadin apps using Push over WebSockets. You can see this message in your browser’s Network tab: it’s marked with the HTTP Status 101. 101 is http code for upgrade to websocket, that’s OK to see.
The heartbeat character is reconfigurable on server-side
via ApplicationConfig.HEARTBEAT_PADDING_CHAR
- the javadoc says it’s ' '
(space) but in reality it’s
‘X’ as seen in HeartbeatInterceptor.paddingBytes
. You use the org.atmosphere.interceptor.HeartbeatInterceptor.paddingChar
configuration option to reconfigure the character: place a breakpoint into HeartbeatInterceptor.configure()
to
learn the effective value.
On the client side, you can check for the effective value of the padding character as follows:
the first message sent over Vaadin Push looks like this: 41|52a917c0-9c19-455a-a0d4-b155f46a3ed3|0|X|
. Pay attention
to the end of the message: the 0|X|
configures the heartbeat padding to the X
character.
Vaadin then configures Atmosphere to the ‘X’ padding character, causing Atmosphere to automatically ignore 1|X
messages.
It could be that your server sends a different padding character, e.g. A
but then proceeds to send 1|X
heartbeat
messages, which then get passed to Vaadin, which then fails since Vaadin expects the UIDL JSON document.
Double-wrapped messages
If you’re receiving 3|1|X
then that’s wrong - it should be 1|X
. Looks like there’s “another” Atmosphere
which wraps the message “1|X” (the message ‘X’ of size 1) to “3|1|X” (the message ‘1|X’ of size 3).
TODO how to solve this.
History
The X
message used to be hard-coded in Vaadin client; changing it server-side would cause the
client to fail. The algorithm was changed since then to detect the padding character from the first message,
see this flow commit
for more details.
Workarounds
Workaround is to disable Atmosphere heartbeat mechanism, relying on Vaadin’s
heartbeat mechanism only. Increase org.atmosphere.interceptor.HeartbeatInterceptor.heartbeatFrequencyInSeconds
to some absurdly high value,
see ApplicationConfig.HEARTBEAT_INTERVAL_IN_SECONDS
in Atmosphere for more details.
Configuring Atmosphere
Create a servlet which extends VaadinSevlet and add init parameters such as org.atmosphere.interceptor.HeartbeatInterceptor.paddingChar
to it. See ApplicationConfig
for more configuration options. Atmosphere is configured in Vaadin’s PushRequestHandler
class - you can place
a breakpoint there and check whether your changes took any effect.