2012-11-30 40 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