2012-03-21 29 views
0

我無法獲取sessionscoped bean和ejb有狀態bean以在同一個java-ee容器內的用戶會話之間進行通信。通過試驗和錯誤,我決定使用數據庫在用戶會話之間傳遞消息。但是現在我遇到了一個問題,如何通知用戶的會話數據庫已更改 我可以在每個用戶的會話上下文中啓動後臺輪詢線程來輪詢數據庫的更改嗎?如果這能起作用,避免阻塞的最好方法是什麼,但要確保輪詢bean在自己的用戶會話上下文中「醒來」?cdi會話上下文之間的通信 - 與數據庫,將正確的cdi上下文被調用?

我使用的是Glassfish 3.1.2,用戶會話是CDI sessionscoped bean,以及一些用於JPA數據庫訪問的有狀態EJB。我正在使用CDI事件總線在用戶會話中圍繞bean傳遞消息。

我試圖使用單身人士在用戶會話之間進行通信。但是這並不起作用,因爲一旦將源自用戶1的消息傳遞給用戶2的bean,並且這些bean引發CDI事件,則CDI事件由用戶1的會話上下文處理。這是合理的,因爲消息是在用戶1的會話中創建的。

任何幫助將不勝感激!

回答

4

我想我必須回答我的問題 -

  1. 上下文不會傳播到新的線程或異步調用。這是CDI 1.0規範的未定義行爲,因此不需要容器來跟蹤哪個上下文創建了一個線程。如果創建線程並在線程喚醒後觸發CDI事件,則該CDI事件將沒有活動上下文,並會拋出以下錯誤:org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.RequestScoped或某個特定於您的線程嘗試激活的範圍的內容。 See this Glassfish ticket,這真的不是一個錯誤,它只是未定義的行爲。

  2. 因此,當任何後臺輪詢線程設置爲檢查用戶數據是否有任何更改時,當線程檢測到更改時,它無法與用戶的會話上下文進行通信(通過CDI事件)。該線程此時沒有上下文。這似乎是幾個人未解決的問題:on the jboss forumseam forum

希望我的解決方案能幫上忙。在CDI 1.1定義一種將會話上下文傳播到線程的方法之前,您必須讓用戶輪詢自己的數據,當他們獲得新數據時,他們可以在自己的會話上下文中對其執行操作。我建立了自己的系統,使用數據庫爲每個用戶存儲一個事件隊列,當他們輪詢時,他們只是遍歷隊列中的消息並將它們關閉,就好像它們是在自己的會話上下文中發送的CDI消息一樣。

如果焊接CDI專家可以糾正我,如果我錯了,我將不勝感激!

0

我不認爲CDI事件總線可以用於用戶會話之間的通信。

用JMS消息代理解決這個問題不是更好嗎?你的應用程序可以擴展得更好!將其作爲單獨的實例運行或將其嵌入到應用程序服務器中。 例如,您可以使用ActiveMQ代理。

在JMS主題上發佈通知消息,並使用戶會話訂閱它。 我還沒有使用Seam 3 JMS module,但它看起來能夠彌補JMS和CDI之間的差距。使用Seam JMS,您可以在每個用戶會話中接收JMS消息。文檔中的示例說明了如何爲每個用戶在@SessionScoped bean的@PostConstruct中註冊JMS偵聽器。

+0

不,它不會工作 - 我試過了。當接收到JMS消息時,接收Bean沒有上下文 - 由於消息接收Bean(偵聽器方法或MDB)超出範圍,它無法發送會話範圍上下文事件到現有會話。你會得到我上面提到的WELD-001303例外。 – 2012-03-30 17:17:08

相關問題