2013-10-06 3 views
5

Я использую поддержку JSR-356 WebSocket в Tomcat 8 для управления приложением, над которым я работаю. Пока что все сообщения обрабатываются в одном потоке. Хотя я понимаю причины этого - и почему websockets реализованы таким образом, есть ли способ использовать ExecutorService для обработки сообщения, которое приходит (без создания ExecutorService в моем коде)?Tomcat 8 JSR 356 WebSocket Threading

Это позволит обеспечить масштабируемость 1 (или только нескольких) потоков сетевого селектора (для поддержки большого количества подключенных клиентов), позволяя стандартную обработку фактического сообщения на основе потоков (когда требуется сообщение для обработки клиентом).

Я не вижу ничего особенного, что позволило бы это изменить.

ответ

13

Модель резьбы зависит от того, какой разъем вы используете. Для масштабирования вы хотите использовать NIO (по умолчанию) или APR/native (багги с 8.0.0-RC3). На данный момент NIO - единственный выбор. Проблемы APR/native должны быть исправлены в ближайшее время (я работал над этим, когда увидел этот вопрос).

NIO использует селектор и пул потоков для обработки принятых сообщений. Когда селектор обнаруживает, что данные доступны, он передает сокет в поток из пула потоков (через исполнителя) для его обработки. Эта обработка может привести к буферизации данных внутри страны, причем приложение уведомляется о частичном сообщении, причем приложение уведомляется о полном сообщении или их комбинации. Уведомление о приложении обрабатывается тем же потоком, который обрабатывает входящие данные.

Если несколько сообщений получены от нескольких клиентов, то для обработки этих сообщений будет отправлено несколько потоков.

В API JSR 356 нет функциональности, позволяющей приложению выбирать сообщения или частичные сообщения, которые должны обрабатываться через ExecutorService, когда приложение было уведомлено о новом сообщении без применения приложения. Это приложение должно быть относительно простым для приложения, которое обрабатывает только целые сообщения для его реализации. Если приложения обрабатывают частичные сообщения, это будет намного сложнее.

APR/native (один раз фиксированный) будет вести себя так же, как NIO. BIO всегда использует блокировку IO (даже если API JSR356 указывает на неблокирование), а также требует одного потока для каждого подключенного клиента, а не одного потока для каждого подключенного клиента с данными для обработки.

+0

Итак, вы говорите, что он использует пул потоков для обработки входящих данных? Существует ли максимум одного потока на клиента? –

+0

Я спрашиваю, потому что, когда я тестировал, это выглядело так, как будто второе сообщение ожидало завершения первой обработки. Но мы оба отправлены с той же сессии (возможно, именно поэтому). Замечание стороны: отличный ответ –

+3

Существует не более одного потока, выделенного для обработки данных для каждого клиента. Если клиент отправляет несколько сообщений, они будут обрабатываться последовательно - возможно, одним и тем же потоком. Когда поток завершит первое сообщение, он увидит, что есть больше данных для чтения. Если есть, он прочитает его. Если нет, сокет возвращается к Selector/Poller, пока не поступит больше данных. Данные должны обрабатываться таким образом. Там, где есть возможность для большего количества потоков, когда сообщение (или частичное сообщение) готово к передаче в приложение, это может быть сделано в новом потоке (но это не так). –

Смежные вопросы