2013-10-06 23 views
5

我使用Tomcat中8 JSR-356 WebSocket的支持,从而推动我工作的应用程序。到目前为止,它看起来像所有的消息都在一个线程中处理。虽然我明白这背后的原因 - 以及为什么websockets以这种方式实现,是否有任何方法可以使用ExecutorService来处理进来的消息(而不是在我的代码中创建ExecutorService)?Tomcat的8 JSR 356的WebSocket线程

这将允许具有1个(或仅少数)网络选择器线程(以支持大量连接的客户端)的可扩展性,同时允许对实际消息进行标准的基于线程的处理(当消息需要时为客户处理)。

我看不出有什么特别,将允许这种改变。

回答

13

的线程模型取决于你所使用的连接器而异。对于想要使用NIO(缺省值)或APR/native(从8.0.0-RC3开始)的可扩展性。 NIO是目前唯一的选择。 APR /原生问题应该很快修复(当我看到这个问题时,我正在研究这个问题)。

NIO使用选择和线程池来处理接收到的消息。当选择器检测到数据可用时,它将套接字传递给线程池中的线程(通过执行程序)以进行处理。该处理可能导致数据在内部被缓冲,应用程序被通知部分消息,应用程序被通知完整消息或这些消息的组合。对应用程序的通知由处理传入数据的相同线程处理。

如果从多个客户端收到多封邮件,然后多线程将被分派到处理这些信息。

JSR 356 API中没有任何功能允许应用程序选择通过ExecutorService处理的消息或部分消息,其中一个应用程序在没有应用程序执行的情况下收到新消息通知。对于仅处理整个消息来执行此操作的应用程序来说,这应该相对简单。如果应用程序处理部分消息,那么它会更困难。

APR /天然的(一旦固定)将表现方式与NIO相同。 BIO始终使用阻塞IO(即使在JSR356 API指示非阻塞的情况下),并且每个连接的客户端也需要一个线程,而不是每个连接的客户端需要一个线程来处理数据。

+0

好吧,你是说它确实使用线程池来处理传入数据?每个客户端是否有最多一个线程? –

+0

我问,因为当我测试时,它看起来像第二条消息正在等待第一个完成处理。但是,我们都是从同一个会话发出的(也许这就是为什么)。附注:很好的答案 –

+3

分配给每个客户端处理数据的线程不会超过一个。如果一个客户端发送多个消息,那么它们将按顺序处理 - 可能是由相同的线程处理。当线程完成第一条消息时,它会查看是否有更多数据要读取。如果有,它会读取它。如果没有,套接字将返回到选择器/轮询器,直到更多数据到达。数据必须以这种方式处理。在有更多线程的地方,一旦消息(或部分消息)准备好传递给应用程序,就可以在新线程中完成(但不是)。 –