Atmosphere Framework Websocket返回空responseBody

时间:2016-06-13 22:03:21

标签: spring websocket spring-boot atmosphere atmosphere.js

我正在使用基于此onetwo示例项目的大气框架的Spring-Boot(嵌入式容器)。

我试图从一个资源做一个非常简单的广播,浏览器接收消息但是responseBody是空字符串“”。我通过Atmosphere的大部分代码进行了调试,并且我可以告诉我,我的JSON消息已成功添加到异步写入队列,但仍然在浏览器中显示为空。

我首先想到的可能是Atmosphere正在过滤消息,但调试显示它不是。

enter image description here

相关POM.xml

<spring-boot-starter-web.version>1.3.3.RELEASE</spring-boot-starter-web.version>
<atmosphere-runtime.version>2.2.4</atmosphere-runtime.version>
<atmosphere-javascript.version>2.2.3</atmosphere-javascript.version>

相关的TRACE日志:

17:39:59.813 TRACE o.atmosphere.cpr.DefaultBroadcaster - /websocket/notifications is about to broadcast Entry{message={"id":1,"msg":"Hello, World"}, type=ALL, future=org.atmosphere.cpr.BroadcasterFuture@15c404ca} 

大气配置

package com.hello;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.atmosphere.cache.UUIDBroadcasterCache;
import org.atmosphere.cpr.ApplicationConfig;
import org.atmosphere.cpr.AtmosphereFramework;
import org.atmosphere.cpr.AtmosphereServlet;
import org.atmosphere.cpr.MetaBroadcaster;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AtmosphereConfiguration implements ServletContextInitializer {

    @Bean
    public AtmosphereServlet atmosphereServlet() {
        return new AtmosphereServlet();
    }

    @Bean
    public AtmosphereFramework atmosphereFramework() {
        return atmosphereServlet().framework();
    }

    @Bean
    public MetaBroadcaster metaBroadcaster() {
        AtmosphereFramework framework = atmosphereFramework();
        return framework.metaBroadcaster();
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        configureAthmosphere(atmosphereServlet(), servletContext);
    }

    private void configureAthmosphere(AtmosphereServlet servlet, ServletContext servletContext) {
        ServletRegistration.Dynamic atmosphereServlet = servletContext.addServlet("atmosphereServlet", servlet);
        atmosphereServlet.setInitParameter(ApplicationConfig.ANNOTATION_PACKAGE, "com.hello");
        atmosphereServlet.setInitParameter(ApplicationConfig.BROADCASTER_CACHE, UUIDBroadcasterCache.class.getName());
        atmosphereServlet.setInitParameter(ApplicationConfig.BROADCASTER_SHARABLE_THREAD_POOLS, "true");
        atmosphereServlet.setInitParameter(ApplicationConfig.BROADCASTER_MESSAGE_PROCESSING_THREADPOOL_MAXSIZE, "10");
        atmosphereServlet.setInitParameter(ApplicationConfig.BROADCASTER_ASYNC_WRITE_THREADPOOL_MAXSIZE, "10");
        servletContext.addListener(new org.atmosphere.cpr.SessionSupport());
        atmosphereServlet.addMapping("/websocket/*");
        atmosphereServlet.setLoadOnStartup(0);
        atmosphereServlet.setAsyncSupported(true);
    }

}

大气资源

package com.hello;

import java.nio.charset.StandardCharsets;

import org.atmosphere.config.service.Disconnect;
import org.atmosphere.config.service.ManagedService;
import org.atmosphere.config.service.Ready;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ManagedService(path = NotificationAtmosphereResource.PATH)
public class NotificationAtmosphereResource {

    public static final String PATH = "/websocket/notifications";

    private Logger logger = LoggerFactory.getLogger(NotificationAtmosphereResource.class);

    public void init(AtmosphereResource resource){
        resource.getResponse().setCharacterEncoding(StandardCharsets.UTF_8.name());
    }

    @Ready
    public void onReady(final AtmosphereResource resource) {
        logger.info("Connected {}", resource.uuid());
    }

    @Disconnect
    public void onDisconnect(AtmosphereResourceEvent event) {
        logger.info("Client {} disconnected [{}]", event.getResource().uuid(),
                (event.isCancelled() ? "cancelled" : "closed"));
    }

}

我发出消息的服务

package com.hello;

import org.atmosphere.cpr.MetaBroadcaster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class NotificationEmitterBean implements NotificationEmitter {

    private Logger logger = LoggerFactory.getLogger(NotificationEmitterBean.class);

    @Autowired 
    private MetaBroadcaster metaBroadcaster;

    @Autowired
    private NotificationService notificationService;

    @Autowired
    private JsonMapper jsonMapper;

    @Override
    public void emitForJob(String msg) {
   metaBroadcaster.broadcastTo(NotificationAtmosphereResource.PATH, 
                    jsonMapper.toJson(msg));        
        }

    }

}

1 个答案:

答案 0 :(得分:0)

我简直不敢相信我之前没有尝试过,但是在使用console.dir登录时,它在控制台中没有显示JSON实际存在!!

我不知道为什么console.dir(response)会显示一个空字符串responseBody。

websocketRequest.onMessage = function(response) {

  // This produces the image in my original question displaying an empty responseJson. Can anyone explain why?
  console.dir(response);

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

  console.log(message);

  $rootScope.$apply(function() {
    messages.push(message);
  });
};