我遇到了一些訪問PushContext
實例的問題。在與託管bean分開運行的線程中訪問OmniFaces PushContext實例
我想發送一個線程中的消息,這個線程與託管bean分開運行。通過@Injected @Push
注射,我不能。有沒有人有任何想法我可以做到這一點?
我遇到了一些訪問PushContext
實例的問題。在與託管bean分開運行的線程中訪問OmniFaces PushContext實例
我想發送一個線程中的消息,這個線程與託管bean分開運行。通過@Injected @Push
注射,我不能。有沒有人有任何想法我可以做到這一點?
在線程訪問OmniFaces PushContext實例
的PushContext
只能在一個容器管理工件駐留在WAR(例如@Named
,@WebServlet
,@WebFilter
,@WebListener
等)注入,而不是在其他地方(即絕對不在@Stateless
,@Stateful
,@Singleton
等)。
我想送從託管bean
如果線程是由容器管理它只會工作分開運行的線程內的信息,比如一個由啓動EJB的@Asynchronous
。如果該線程未被管理(即使用Thread
手動創建),它將不起作用。這在Is it safe to start a new thread in a JSF managed bean?
中詳細解釋當EJB的@Asynchronous
正確使用時,那麼只需按照<o:socket>
文檔中的示例進行操作即可。您可以在EJB design hints部分找到它們。
從documentation以下提取物顯示出如何把一個應用通過其又通過一些後臺作業(例如@Schedule
)調用的@Asynchronous
EJB方法作用域插座。
如果您想要觸發從EAR/EJB端推送到應用程序範圍的推送套接字,那麼您可以使用CDI事件。首先創建一個代表push事件的自定義bean類,就像下面的PushEvent一樣,將你想要傳遞的任何東西作爲推送消息。
public final class PushEvent { private final String message; public PushEvent(String message) { this.message = message; } public String getMessage() { return message; } }
然後用
BeanManager.fireEvent(Object, java.lang.annotation.Annotation...)
來觸發CDI事件。@Inject private BeanManager beanManager; public void onSomeEntityChange(Entity entity) { beanManager.fireEvent(new PushEvent(entity.getSomeProperty())); }
最後只是@Observes它有一定的要求或應用範圍的CDI在WAR託管bean,並委託給下面PushContext。
@Inject @Push private PushContext someChannel; public void onPushEvent(@Observes PushEvent event) { someChannel.send(event.getMessage()); }
的下方提取從documentation顯示瞭如何推向會話或視圖作用域插座通過其又通過一些JSF動作調用的@Asynchronous
EJB方法。
如果EAR/EJB端的觸發器是在WAR端啓動的異步服務方法,那麼您可以利用WAR端的回調。讓業務服務方法以回調實例爲參數,例如
java.util.function.Consumer
功能接口。@Asynchronous public void someAsyncServiceMethod(Entity entity, Consumer<Object> callback) { // ... (some long process) callback.accept(entity.getSomeProperty()); }
並調用WAR中的異步服務方法如下。
@Inject private SomeService someService; @Inject @Push private PushContext someChannel; public void someAction() { someService.someAsyncServiceMethod(entity, message -> someChannel.send(message)); }