Для студенческого проекта разрабатываю некое подобие мессенджера, соединение - через сокеты. Каким лучше способом обрабатывать потоки на сервере? Пока что есть два варианта:
1) Каждого клиента при подключении кидаем в отдельный поток, в котором в течение всего подключения работаем с базой, отправляем сообщения получателям, etc. Но такой подход сильно ограничит количество одновременно работающих пользователей.
2) Создаём тредпул на ограниченное количество потоков, и обрабатываем там приходящие сообщения. Но как в данном случае отправить сообщение получателю, ведь у нас нет открытого сокета с ним? Можно хранить в базе ip последнего подключения в базе, но это не решит проблему с отсутствием открытого сокета.
Каким образом всё-таки будет лучше всё это организовать?
Количество потоков не равно количеству открытых сокетов. Расходовать на каждое подключение отдельный поток ни в коем случае нельзя. Но синхронно закрывать сокет после обработки подключения совсем не обязательно. Сокет - просто значение ячейки массива (или карты) будет взято и использовано когда понадобится в любом потоке (работа с конкретным сокетом, конечно, должна быть обернута в соответствующий синхроблок). Единственно, о чем не следует забывать это - KeepAlive пинги (отдельный пул потоков и таймера под них, например), которые обеспечивают сразу две задачи: 1) помогают удержать неактивное соединение (умные роутеры любят закрывать "мертвые" соединения, и клиент, в зависимости от реализации, может делать то же). 2) очищают список сокетов от реально мертвых.
Будет ли эффективен прямолинейный путь - создание потока, который будет пробегать по карте сокетов и проверять, available ли соответствующий данному сокету inputStream?