2016-12-15 45 views

回答

1

在線程訪問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)); 
} 
相關問題