Atmosphere responses, broadcasts do not call javas

2019-02-18 23:05发布

问题:

I'm working with atmosphere trying to get the simple base implementation using atmosphere 2.0.3 tomcat 7.0.42 running locally in my eclipse environment (also connecting from external machine to see traffic with wireshark). The problem I am experiencing is no matter what transport I use, websocket, sse, polling, long-polling, the broadcast response never seems to get to the client and the response.OnMessage handler is never invoked. I receive no exceptions during runtime, and I have tried with firefox/chrome/and IE. I have also used wireshark and I see a packet after the post of a chat message that contains my message response: "HTTP - Continuation or non-HTTP traffic" and in the packet data I can see the outgoing message to the client, so it appears the server side is working correctly. The initial connection to server is established and the js onOpen handler is invoked as expected.

The work I am doing is based largely on the atmosphere sample chat application. If anyone has any suggestions, I would appreciate it. Might also be worth mentioning, that I added in the actual chat handler, js, and html page from the atmosphere sample and it also does not behave and the onMessage js handler is not invoked in that either, so I'm thinking it is a configuration issue.

web.xml

<servlet>
    <description>AtmosphereServlet</description>
    <servlet-name>AtmosphereServlet</servlet-name>
    <servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
   <init-param>
        <param-name>o.a.useWebSocket</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>org.atmosphere.useNative</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
    <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
    <servlet-name>AtmosphereServlet</servlet-name>
    <url-pattern>/chat/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>AtmosphereServlet</servlet-name>
    <url-pattern>/chatSample/*</url-pattern>
</servlet-mapping>

POM.xml

<dependency>
  <groupId>javax.activation</groupId>
  <artifactId>activation</artifactId>
  <version>1.1.1</version>
</dependency>
<dependency>
    <groupId>org.atmosphere</groupId>
    <artifactId>atmosphere-compat-tomcat</artifactId>
    <version>1.0.15</version>
</dependency>
<dependency>
    <groupId>org.atmosphere</groupId>
    <artifactId>atmosphere-compat-tomcat7</artifactId>
    <version>1.0.15</version>
</dependency>
<dependency>
    <groupId>org.atmosphere</groupId>
    <artifactId>atmosphere-runtime</artifactId>
    <version>2.0.3</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.3</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.3</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
</dependency>

Server side code:

@AtmosphereHandlerService(path="/chat",
broadcasterCache = UUIDBroadcasterCache.class,
interceptors = { AtmosphereResourceLifecycleInterceptor.class,
                 BroadcastOnPostAtmosphereInterceptor.class,
                 HeartbeatInterceptor.class
               })
public class ChatController extends OnMessage<String> {

    private final ObjectMapper mapper = new ObjectMapper();

    @Override
    public void onMessage(AtmosphereResponse response, String message) throws IOException {
        response.write(mapper.writeValueAsString(mapper.readValue(message, Data.class)));
    }
}

Client side Javascript (has been tried with polling/long-polling/sse/websockets and all successfully connect initially and call the OnOpen handler after initial connection:

var transport = 'long-polling';

var request = { url:'/Chat2/chat',
    contentType : "application/json",
    logLevel : 'debug',
    transport : transport,
    trackMessageLength : true,
    reconnectInterval : 5000,
    fallbackTransport: 'polling'};


request.onOpen = function(response) {
    console.log('OnOpen: Atmosphere connected using ' + response.transport );
    transport = response.transport;
};

request.onReopen = function(response) {
    console.log('OnReopen: connection reopened');
};


request.onTransportFailure = function(errorMsg, request) {
    atmosphere.util.info(errorMsg);
    if (window.EventSource) {
        request.fallbackTransport = "polling";
    }
    console.log('OnTransportFailure: Atmosphere Chat. Default transport is WebSocket, fallback is ' + request.fallbackTransport);
};

request.onMessage = function (response) {
    alert('OnMessage: message received');
};

request.onClose = function(response) {
    console.log('OnClose: Client closed the connection after a timeout');
    subSocket.push(atmosphere.util.stringifyJSON({ author: author, message: 'disconnecting' }));
};

request.onError = function(response) {
    console.log('OnError: error occurred');
    console.log(response);
    logged = false;
};

request.onReconnect = function(request, response) {
    console.log('OnReconnect: Reconnected');
};

subSocket = socket.subscribe(request);

$('#chatSubmit').click(function() {
    var msg = $('#chatText').val();

    subSocket.push(atmosphere.util.stringifyJSON({ author: author, message: msg }));
    $('#chatText').val('');
});

回答1:

you must install the TrackMessageLengthInterceptor if you set the trackMessageLength : true on the client side. So add it to your AtmosphereHandlerService's interceptor list.

-- Jeanfrancois