【问题标题】:Atmosphere Framework Websocket Returns Empty responseBodyAtmosphere Framework Websocket 返回 Empty responseBody
【发布时间】:2016-06-13 22:03:21
【问题描述】:

我正在使用基于 onetwo 示例项目的带有 Atmosphere Framework 的 Spring-Boot(嵌入式容器)。

我正在尝试从一个资源进行非常简单的广播,浏览器接收到消息但 responseBody 是空字符串“”。我调试了很多 Atmosphere 代码,据我所知,我的 JSON 消息已成功添加到异步写入队列中,但在浏览器上仍然为空。

起初我认为可能是 Atmosphere 正在过滤掉消息,但调试显示它不是。

相关的 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));        
        }

    }

}

【问题讨论】:

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


    【解决方案1】:

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

    我不知道为什么 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);
      });
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-14
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      • 2012-09-20
      • 2014-12-06
      • 2014-10-28
      相关资源
      最近更新 更多