当前位置: 首页 > 知识库问答 >
问题:

如何从服务器中运行的线程触发CDI事件?

南门野
2023-03-14

我希望运行在线程中的udp服务器在每次接收到数据报时都会触发一个事件,并发送格式为json的数据。

    public class UDPServer extends Thread {

        private SocketUDPCommunication comm;

        @Inject @Notify
        private StatusChangeHandler sch;

        public UDPServer() {
            comm = new SocketUDPCommunication();
        }


        @Override
        public void run() {

            DatagramPacket response;

            comm.setPort(Utils.UDP_SERVER_PORT);
            comm.createSocket();

            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("Waiting for clients to connect on port:" + comm.getSocket().getLocalPort());
                try {
                    response = comm.receiveResponse();
                } catch (SocketTimeoutException e) {
                    continue;
                }                           

                byte[] byteSend = comm.discardOffset(response);

                Status status = frameToJson(byteSend);

                Genson genson = new Genson();
                String json = genson.serialize(status);

                sch.sendChangedStatus(json);    //Raise the cdi event, sch not initialized!!
            }

        }

        @Override
        public void interrupt() {
            super.interrupt();
            comm.closeConnection();
        }
    }

已为此事件定义了一个侦听器,它将调用websocketendpoint方法向所有连接的客户端广播此消息:

    public class StatusChangeObserver {

        public void statusChanged(@Observes StatusChange sce) {
            WebsocketEndPoint.sendAll(sce.getJson());
        }
    }

    @ServerEndpoint(value="/websocket")
    public class WebsocketEndPoint {
        private static Set<Session> userSessions = Collections.synchronizedSet(new HashSet<Session>());

        @OnOpen
        public void onOpen(Session userSession) {
            System.out.println("Opening new connection");
            userSessions.add(userSession);
        }

        @OnClose
        public void onClose(Session userSession) {
            System.out.println("Connection closed. Id: " + userSession.getId());
            userSessions.remove(userSession);
        }


        public static void sendAll(String message) {
            for (Session session : userSessions) {
                if (session.isOpen()) {
                    session.getAsyncRemote().sendText(message);
                }
            }     
        }
    }

以及实际触发事件的处理程序:

    @Notify
    public class StatusChangeHandler {

        @Inject
        private Event<StatusChange> statusChangedEvent;

        public void sendChangedStatus(String json) {
            StatusChange sce = new StatusChange(json);
            statusChangedEvent.fire(sce);
        }
    }

StatusChange是一个简单的POJO,其中包含要广播的消息。@Notify限定符:

    @Qualifier
    @Retention(RUNTIME)
    @Target({METHOD, FIELD, PARAMETER, TYPE})
    public @interface Notify {
    }

这些是依赖项注入的第一步,因此我不太确定应该如何从线程内触发事件,以及如何初始化sch对象。我发现这个页面建议使用WeldWeldContainer类来初始化CDI,但我无法在maven中找到这个类。这是正确的方法吗?在这种情况下,有人知道如何将这些类包含到我的项目中吗?

共有2个答案

解阳泽
2023-03-14

因为您使用的是Tomcat,所以我们讨论的是servlet环境。为此,Weld提供了一个servlet JAR,它将自动为您引导CDI。无需手动处理焊接/焊接容器

这里有一个到Weld文档的链接,它解释了您需要的工件/依赖项以及如何使用它。

添加这些之后,CDI应该在您将应用程序部署到Tomcat时为您简单地引导。

丰飞龙
2023-03-14

这里有一个带有weld库的公共存储库。

https://mvnrepository.com/artifact/org.jboss.weld

但是,你需要什么?在什么环境下你会使用它?例如,在wildfly中,集成了cdi 1.1或cdi 1.2,您无需添加此库。

有关更多信息,请使用http://weld.cdi-spec.org/

 类似资料:
  • http://www.html5rocks.com/en/tutorials/eventsource/basics/ 但是,我不明白一个重要的概念--是什么触发了服务器上导致消息发送的事件? 换句话说--在HTML5示例中--服务器只发送一次时间戳: 如果我建立一个实际的例子--例如,一个Facebook风格的“墙”或一个股票报价器,在这个例子中,每当某个数据发生变化时,服务器就会向客户机“推送”

  • 问题内容: 在MS SQL Server 2008 R2中,我们需要一个预插入和预更新触发器,该触发器可以检查某些内容并允许(或通过)回滚正在运行的插入/更新。 问题 :触发。是否真的需要显式地编写插入或更新?因为我们希望完成默认的插入或更新操作,所以仅执行“预检查”。 问题答案: 是的。 您确实需要编写显式或。 触发器运行DML操作。如果将触发器留为空白,则除了/表将在创建和填充中/之外,将不会

  • 我使用服务总线触发器创建了一个azure函数,当我尝试运行该函数时,我得到了这个错误: 我为开发存储设置了local.settings.json文件 我在使用AzureWebJobsStorage的函数中有连接字符串 我不知道是什么问题。如果有任何帮助,将不胜感激。

  • REST服务器可以配置为订阅从已部署的业务网络发出的事件,并发布这些业务事件供客户端应用程序使用。目前,REST服务器支持通过WebSockets向客户端应用程序发布事件。 客户端应用程序可以使用WebSocket客户端来订阅由REST服务器发布的业务事件。WebSocket客户端可用于所有主要编程语言和应用程序类型,例如客户端Web用户界面、后端服务器进程、移动应用程序和集成工具。 启用WebS

  • 我试图远程评测运行在64位linux服务器上的alfresco,该服务器运行1.8 JVM和Apache Tomcat 7。xx来自我的测试代码,但不知道如何通过编程触发快照。 我想做的是连接到远程服务器,开始分析,并从用Java编写的测试代码中将该服务器性能的快照保存到本地机器上。 我已经在linux服务器上安装了JProfiler 9.2,可以通过JProfiler GUI连接并拍摄快照。为了

  • 然后是数据报通道、pipelineFactory和Bootstrap: 在pipelineFactory中,getPipeline()添加自定义处理程序。 就像中所说的:UDP消息的多线程处理 然后我根据这些条目修改了一些代码。现在创建线程池的条件是: 和ExecutionHandler的pipelineFactory: getPipeline()添加处理程序,如所描述的: 但它们不同时处理。me