Atmosphere: Subscription not reaching server

594 Views Asked by At

Looks like subscriptions are not reaching my server.

My server side subscription method prints to the Tomcat console when a subscription is made. I'm not seeing this log when I load the web page

  • browser console says websocket open successfully
  • request.onOpen isn't getting hit
  • request.onMessage isn't getting hit
  • I see the log in the Tomcat console when I go to the subscription url directly (without all the querystring params atmosphere adds in) in a browser.

Stack: Atmosphere 2.2.3, Atmosphere-Jersey 2.2.3, Jersey-Jason 1.6, Servlet 3, Java 7, Tomcat 7.0.56

JavaScript

$(function () {
    "use strict";

    var content = $('#content');
    var input = $('#input');
    var status = $('#status');
    var logged = false;
    var socket = $.atmosphere;
    var request = { url: 'http://localhost:8080/atmospherePOC/rest/subscription',
                    contentType : "application/json",
                    logLevel : 'debug',
                    transport : 'websocket' ,
                    trackMessageLength : true,
                    fallbackTransport: 'long-polling'};


    request.onOpen = function(response) {
        content.html($('<p>', { text: 'Atmosphere connected using ' + response.transport }));
    };

    request.onMessage = function (response) {
        var message = response.responseBody;
        try {
            var json = jQuery.parseJSON(message);
        } catch (e) {
            console.log('This doesn\'t look like a valid JSON: ', message);
            return;
        }

        content.append('<p><span style="color:">' + json.identifier + ' Buy' + json.buy +' Sell ' + json.sell +'</span>' + '</p>');
    };

    request.onClose = function(response) {
        logged = false;
    }

    request.onError = function(response) {
        content.html($('<p>', { text: 'Sorry, but there\'s some problem with your '
            + 'socket or the server is down' }));
    };

    socket.subscribe(request);
});

Subscription handler:

@Path("subscription")
public class CurrencyPairSubscription {

    @GET
    @Suspend
    public Broadcastable subscribeToQuote(@Context final BroadcasterFactory broadcasterFactory) {

        System.out.println("New subscriber");
        return new Broadcastable(broadcasterFactory.lookup("A_TOPIC", true));
    }
}

Web.xml

<?xmlns:j2ee="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee    http://java.sun.com/xml/ns/j2ee/web-app_2.5.xsd">

    <description>AtmosphereServlet</description>
    <display-name>AtmosphereServlet</display-name>
    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>resteasy.scan.providers</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>resteasy.scan.resources</param-name>
        <param-value>false</param-value>
    </context-param>
    <servlet>
        <description>AtmosphereServlet</description>
        <servlet-name>AtmosphereServlet</servlet-name>
        <servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
        <!-- If you want to use Servlet 3.0 -->
        <async-supported>true</async-supported>
        <!-- List of init-param -->
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.foo</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>AtmosphereServlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>BroadcasterServlet</servlet-name>
        <servlet-class>com.foo.broadcaster.BroadcasterServlet</servlet-class>
    </servlet>
     <servlet-mapping>
        <servlet-name>BroadcasterServlet</servlet-name>
        <url-pattern>/broadcasterServlet/*</url-pattern>
    </servlet-mapping>

</web-app>
1

There are 1 best solutions below

0
On BEST ANSWER

After a lot of banging my head on the desk, I got this working*. The trick was to not pass headers in the query string. You acomplish this while building the request in JavaScript:

$(function () {
    "use strict";

    var content = $('#content');
    var input = $('#input');
    var status = $('#status');
    var logged = false;
    var socket = $.atmosphere;
    var request = { url: 'http://localhost:8080/atmospherePOC/rest/subscription',
                    contentType : "application/json",
                    logLevel : 'debug',
                    transport : 'websocket' ,
                    trackMessageLength : true,
                    fallbackTransport: 'long-polling' ,
                    attachHeadersAsQueryString: false}

With this change, the subscription request hits the server.

*Word of caution, the whole app isn't working, still having issues so can't say 100% this works but seeing the logger from the server side is a good indication