2012-11-30 14 views
4

我在我的Spring MVC应用程序中使用Atmosphere来促进推送,使用streaming传输。环境:多个订阅超过单个HttpConnection

在我的应用程序的整个生命周期中,客户端将订阅和取消订阅许多不同的主题。

大气似乎每个订阅都使用一个http连接 - 即每个调用$.atmosphere.subscribe(request)都会创建一个新的连接。这很快耗尽了从浏览器到大气服务器的连接数量。

我不希望每次都创建一个新资源,而是希望能够在广播公司初次创建后为其添加和删除AtmosphereResource

但是,由于AtmosphereResource是入站请求的一对一表示,每次客户端向服务器发送请求时,它都会到达新的AtomsphereResource,这意味着我无法引用原始资源,并将其附加到主题的Broadcaster

我试过使用$.atmosphere.subscribe(request)atmosphereResource.push(request)调用从原始subscribe()返回的资源。但是,这没有什么区别。

解决这个问题的正确方法是什么?

+0

我有完全一样的问题:客户端订阅的广播公司在一个连接,与客户端添加,随意拔插广播。尽管我在测试中并没有达到你的水平。你有没有进一步与此?当然应该有可能吗?你尝试过邮件列表吗? – Fletch

+0

@Fletch是的,得到了​​它,感谢来自IRC频道的家伙的一些指示。下面发布我的解决方案 –

回答

9

这里就是我得到了它的工作:

首先,当客户端初始连接,确保特定的氛围,报头由浏览器调用suspend()之前接受:

@RequestMapping("/subscribe") 
public ResponseEntity<HttpStatus> connect(AtmosphereResource resource) 
{ 
    resource.getResponse().setHeader("Access-Control-Expose-Headers", ATMOSPHERE_TRACKING_ID + "," + X_CACHE_DATE); 
    resource.suspend(); 
} 

然后,当客户端发送额外的订阅请求时,虽然它们有不同的resource,但它们包含原始资源的ATMOPSHERE_TRACKING_ID。这使您可以通过resourceFactory看看它:

@RequestMapping(value="/subscribe", method=RequestMethod.POST) 
public ResponseEntity<HttpStatus> addSubscription(AtmosphereResource resource, @RequestParam("topic") String topic) 
{ 
    String atmosphereId = resource.getResponse().getHeader(ATMOSPHERE_TRACKING_ID); 
    if (atmosphereId == null || atmosphereId.isEmpty()) 
    { 
     log.error("Cannot add subscription, as the atmosphere tracking ID was not found"); 
     return new ResponseEntity<HttpStatus>(HttpStatus.BAD_REQUEST); 
    } 
    AtmosphereResource originalResource = resourceFactory.find(atmosphereId); 
    if (originalResource == null) 
    { 
     log.error("The provided Atmosphere tracking ID is not associated to a known resource"); 
     return new ResponseEntity<HttpStatus>(HttpStatus.BAD_REQUEST); 
    } 

    Broadcaster broadcaster = broadcasterFactory.lookup(topic, true); 
    broadcaster.addAtmosphereResource(originalResource); 
    log.info("Added subscription to {} for atmosphere resource {}",topic, atmosphereId); 

    return getOkResponse(); 
} 
+0

太棒了,非常感谢。 – Fletch

+0

'resource.getResponse()。getHeader(ATMOSPHERE_TRACKING_ID)'似乎不适合我(可能是我的错)。我必须改为调用'atmosphereResource.uuid()'。 – TrogDor

+1

你是如何获得'broadcasterFactory'变量的实例的? – kiltek