首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么企业bean不能监听或接受套接字上的连接?

为什么企业bean不能监听或接受套接字上的连接?
EN

Stack Overflow用户
提问于 2018-01-19 13:36:58
回答 1查看 322关注 0票数 1

我想从像Wildfly这样的Java容器中提供一个套接字,但是在Oracle站点上找到了这个EJB限制。

为什么企业bean不能监听或接受套接字上的连接? 因为如果企业bean正在监听套接字,它就不能被钝化--它必须总是可用的。

我向一位Java专家提出了同样的问题,他回答说:“只有有状态的bean是被动的,所以从单一的无状态启动bean中提供套接字很好,因为它不是被动的”。

但是,我随后查阅了EJB3.2规范,并找到了另一种解释:

企业bean不得尝试在套接字上侦听、接受套接字上的连接离子或使用套接字进行多播。 EJB架构允许企业bean实例成为网络套接字客户端,但不允许它成为网络服务器。允许实例成为网络服务器将与企业bean的基本功能冲突--为EJB客户端服务。

呃。现在我很困惑。我不太明白。

这个限制是否已经过时?这是在没有单例启动bean (< EJB3.1)的时候遗留下来的吗?

如果采用类似于以下(使用Netty)的方法,或者使用Java的ServerSocketChannel (在托管线程中接受客户端连接)的更简单的方法,有什么问题。(不确定Netty是否生成自己的线程)。

谁能解释一下这个限制吗?

代码语言:javascript
复制
@Singleton
@Startup
public class SocketServerBean {

    @Resource
    private ManagedExecutorService managedExecutorService;

    private Channel channel;

    @PostConstruct
    private void startup() {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1, managedExecutorService);
        EventLoopGroup workerGroup = new NioEventLoopGroup(1, managedExecutorService);
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            // ...
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            // Bind and start to accept incoming connections.
            channel = b.bind(6789).channel();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @PreDestroy
    private void shutdown() {
        channel.close();
    }
}
EN

回答 1

Stack Overflow用户

发布于 2018-01-19 14:27:48

为什么企业bean不能监听或接受套接字上的连接?

因为EJB必须充当客户端,而不是服务器。这是确认的EJB3.2规范。技术原因是EJB本质上是可序列化的,而开放流(套接字、文件等)当然是不可序列化的。

功能需求的正确方法是只使用CDI托管bean,而不是EJB。

代码语言:javascript
复制
@ApplicationScoped
public class SocketServerBean {

    public void startup(@Observes @Initialized(ApplicationScoped.class) ServletContext context) {
        // ...

    }

    @PreDestroy
    private void shutdown() {
        // ...
    }
}

@Observes @Initialized(ApplicationScoped.class)将确保在应用程序初始化期间构造它。

在这个CDI托管bean中,如果有必要,您可以直接注入一个EJB。

另请参阅:

与具体问题无关的,手动打开stinks上Java应用程序的套接字。您确定使用这种方法不会遇到另一个XY-问题吗?也许你真的想要使用网络套接字?如果是这样的话,使用JSR-356 @ServerEndpoint代替。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48342386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档