Long-polling with Atmosphere issue with Servlet 2.

2019-09-07 11:40发布

问题:

I'm testing a simple chat application which is using Atmosphere framework. When I connect to the application from two browsers everything works like chat should work with Tomcat 7.0 and Websockets protocol is used.

When I downgrade to Tomcat 6.0. or when I use Weblogic 10.3.6 long-polling is used (as expected). With one browser chatting with itself everything works but when I open second browser both windows are disconnected.

I set the log level to TRACE and it seems that Atmosphere is adding every AtmosphereResource with the same UUID set to 10000:

TRACE [http-8080-6] o.a.c.DefaultAtmosphereResourceFactory [DefaultAtmosphereResourceFactory.java:309] Adding: AtmosphereResource{ uuid=10000, transport=LONG_POLLING, isInScope=true, isResumed=false, isCancelled=false, isSuspended=true, broadcasters=/chat, isClosedByClient=false, isClosedByApplication=false, action=Action{timeout=-1, type=SUSPEND}}

My Chat.java class:

    @AtmosphereHandlerService(path = "/chat", 
broadcasterCache = UUIDBroadcasterCache.class,
                interceptors = {
                        AtmosphereResourceLifecycleInterceptor.class,
                        BroadcastOnPostAtmosphereInterceptor.class,
                        SuspendTrackerInterceptor.class,
                        HeartbeatInterceptor.class
                },
                broadcaster = SimpleBroadcaster.class
        )
        public class Chat extends OnMessage<String> {
            private final Logger logger = LoggerFactory.getLogger(Chat.class);
            private final JacksonDecoder decoder = new JacksonDecoder();
            private final JacksonEncoder encoder = new JacksonEncoder();


        @Override
        public void onMessage(AtmosphereResponse response, String message) throws IOException {
            Message mes = decoder.decode(message);
            logger.info("{} just send {}", mes.getAuthor(), mes.getMessage());
            response.write(encoder.encode(mes));
        }

I'm using Atmosphere version 2.3.1. Unfortunately I need long-polling to work because there Weblogic 10.3.6. installed on our production server and it doesn't support Websocket and has implementation of Servlet 2.5. only.

Edit:

It looks like that during the first GET request to the server, server will set UUID for given AtmosphereRequest and returns it to the server with HTTP header

X-Atmosphere-tracking-id=someUUID

but in the subsequent requsts the client is not using it. It is sending to the server

X-Atmosphere-tracking-id=10000

Not sure if this is correct...

回答1:

After some debuggin I was able to resolve this.

The problem was that in my application.js library I was using

trackMessageLength: true

in request object but there was no TrackMessageSize interceptor defined.

The Atmosphere.js library was parsing following array and instead of 1. value it was taking 2.value and setting it as UUID.

["0af719e9-4776-4af1-9925-19c2bb10b547", "10000", "X", "" ]