gpt4 book ai didi

multithreading - 在与托管 bean 分开运行的线程中访问 OmniFaces PushContext 实例

转载 作者:行者123 更新时间:2023-12-03 13:19:13 29 4
gpt4 key购买 nike

我在访问 PushContext 时遇到了一些问题实例。

我想在与托管 bean 分开运行的线程中发送消息。通过 @Injected @Push 注入(inject), 我不能。有谁知道我该怎么做?

最佳答案

Accessing OmniFaces PushContext instance in thread


PushContext只能注入(inject)驻留在 WAR 中的容器管理工件中(例如 @Named@WebServlet@WebFilter@WebListener等),不能注入(inject)其他地方(即绝对不在 @Stateless@Stateful@Singleton等)。

I would like to send the messages inside a thread that runs separately from the managed 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的摘录显示了如何通过 @AsynchronousEJB 方法推送 应用程序范围的套接字,该方法又由某些后台作业(例如 @Schedule)调用。

In case you'd like to trigger a push from EAR/EJB side to an application scoped push socket, then you could make use of CDI events. First create a custom bean class representing the push event something like PushEvent below taking whatever you'd like to pass as push message.

public final class PushEvent {

private final String message;

public PushEvent(String message) {
this.message = message;
}

public String getMessage() {
return message;
}
}

Then use BeanManager.fireEvent(Object, java.lang.annotation.Annotation...) to fire the CDI event.

@Inject
private BeanManager beanManager;

public void onSomeEntityChange(Entity entity) {
beanManager.fireEvent(new PushEvent(entity.getSomeProperty()));
}

Finally just @Observes it in some request or application scoped CDI managed bean in WAR and delegate to PushContext as below.

@Inject @Push
private PushContext someChannel;

public void onPushEvent(@Observes PushEvent event) {
someChannel.send(event.getMessage());
}


以下来自 documentation的摘录显示了如何通过 @AsynchronousEJB 方法推送到 session View 范围的套接字,该方法又由一些 JSF 操作调用。

In case the trigger in EAR/EJB side is an asynchronous service method which is in turn initiated in WAR side, then you could make use of callbacks from WAR side. Let the business service method take a callback instance as argument, e.g. the java.util.function.Consumer functional interface.

@Asynchronous
public void someAsyncServiceMethod(Entity entity, Consumer<Object> callback) {
// ... (some long process)
callback.accept(entity.getSomeProperty());
}

And invoke the asynchronous service method in WAR as below.

@Inject
private SomeService someService;

@Inject @Push
private PushContext someChannel;

public void someAction() {
someService.someAsyncServiceMethod(entity, message -> someChannel.send(message));
}

关于multithreading - 在与托管 bean 分开运行的线程中访问 OmniFaces PushContext 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41172026/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com